@mastra/mcp 1.14.0 → 1.15.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/client/client.d.ts +41 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/configuration.d.ts +71 -1
- package/dist/client/configuration.d.ts.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/oauth-callback-server.d.ts +117 -0
- package/dist/client/oauth-callback-server.d.ts.map +1 -0
- package/dist/client/oauth-provider.d.ts +38 -2
- package/dist/client/oauth-provider.d.ts.map +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-mcp-overview.md +1 -1
- package/dist/docs/references/reference-tools-mcp-client.md +96 -0
- package/dist/index.cjs +690 -231
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +691 -233
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @mastra/mcp
|
|
2
2
|
|
|
3
|
+
## 1.15.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Complete the OAuth authorization-code loop in MCPClient for HTTP MCP servers. Connections rejected with an authorization error now surface a `needs-auth` state (readable via `getServerAuthState()`), and the new `authenticate(serverName)` method runs the interactive flow end to end: it captures the authorization code on a local loopback callback server (exported as `createOAuthCallbackServer` for hosts with custom redirect handling), exchanges it for tokens, and reconnects. ([#19466](https://github.com/mastra-ai/mastra/pull/19466))
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`8b20926`](https://github.com/mastra-ai/mastra/commit/8b20926cd59e2ba3d66458e062fa0e6e2ada3e68), [`74faf8b`](https://github.com/mastra-ai/mastra/commit/74faf8bd9c1018f2492653c06b1e25fc8300e9e6), [`1fadac4`](https://github.com/mastra-ai/mastra/commit/1fadac44537caeefe81f9f775ae2f2f3d94e9069), [`792ec9a`](https://github.com/mastra-ai/mastra/commit/792ec9a0869bab8274cf5e0ed2840738737a1607), [`712b864`](https://github.com/mastra-ai/mastra/commit/712b864aa1ed12b14c54390ec17b69de163c37f7), [`8f7a5de`](https://github.com/mastra-ai/mastra/commit/8f7a5dedc246cdc938bb65516703cf9b27b03756), [`c0bec73`](https://github.com/mastra-ai/mastra/commit/c0bec732c93d1a22ae5e51ed66cf8cacca8bd6a6)]:
|
|
12
|
+
- @mastra/core@1.52.0-alpha.2
|
|
13
|
+
|
|
3
14
|
## 1.14.0
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
package/dist/client/client.d.ts
CHANGED
|
@@ -8,6 +8,16 @@ import { PromptClientActions } from './actions/prompt.js';
|
|
|
8
8
|
import { ResourceClientActions } from './actions/resource.js';
|
|
9
9
|
import type { ElicitationHandler, ProgressHandler, InternalMastraMCPClientOptions, Root } from './types.js';
|
|
10
10
|
export type { LoggingLevel, LogMessage, LogHandler, ElicitationHandler, ProgressHandler, MastraFetchLike, MastraMCPServerDefinition, InternalMastraMCPClientOptions, Root, RequireToolApproval, RequireToolApprovalFn, RequireToolApprovalContext, } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* OAuth authorization state of an MCP server connection.
|
|
13
|
+
*
|
|
14
|
+
* - `needs-auth`: the server rejected the connection with a 401 and interactive
|
|
15
|
+
* authorization is required (see MCPClient.authenticate)
|
|
16
|
+
* - `authorized`: the server accepted the configured authProvider's credentials
|
|
17
|
+
*
|
|
18
|
+
* Servers without an authProvider never carry an auth state.
|
|
19
|
+
*/
|
|
20
|
+
export type MCPServerAuthState = 'needs-auth' | 'authorized';
|
|
11
21
|
/**
|
|
12
22
|
* Internal MCP client implementation for connecting to a single MCP server.
|
|
13
23
|
*
|
|
@@ -25,6 +35,8 @@ export declare class InternalMastraMCPClient extends MastraBase {
|
|
|
25
35
|
private enableProgressTracking?;
|
|
26
36
|
private serverConfig;
|
|
27
37
|
private transport?;
|
|
38
|
+
private pendingAuthTransport?;
|
|
39
|
+
private _authState?;
|
|
28
40
|
private operationContextStore;
|
|
29
41
|
private exitHookUnsubscribe?;
|
|
30
42
|
private sigTermHandler?;
|
|
@@ -94,6 +106,35 @@ export declare class InternalMastraMCPClient extends MastraBase {
|
|
|
94
106
|
sendRootsListChanged(): Promise<void>;
|
|
95
107
|
private connectStdio;
|
|
96
108
|
private connectHttp;
|
|
109
|
+
/**
|
|
110
|
+
* Closes and clears any transport retained from an unfinished authorization
|
|
111
|
+
* flow. Safe to call when nothing is pending. Centralizes the cleanup so
|
|
112
|
+
* success, disconnect, and forceReconnect all release the same resource.
|
|
113
|
+
*/
|
|
114
|
+
private closePendingAuthTransport;
|
|
115
|
+
/**
|
|
116
|
+
* Records that the server rejected the connection with a 401 and keeps the
|
|
117
|
+
* transport that started the authorization flow so finishAuth can complete it.
|
|
118
|
+
*/
|
|
119
|
+
private markNeedsAuth;
|
|
120
|
+
/**
|
|
121
|
+
* OAuth authorization state of this server connection, when it has an authProvider.
|
|
122
|
+
*
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
get authState(): MCPServerAuthState | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* Completes a pending OAuth authorization-code flow.
|
|
128
|
+
*
|
|
129
|
+
* Exchanges the authorization code captured at the redirect URI on the same
|
|
130
|
+
* transport that started the flow, then leaves the client ready to connect().
|
|
131
|
+
*
|
|
132
|
+
* @param authorizationCode - The authorization code captured at the redirect URI
|
|
133
|
+
* @throws {Error} If no authorization flow is pending for this server
|
|
134
|
+
*
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
finishAuth(authorizationCode: string): Promise<void>;
|
|
97
138
|
private isConnected;
|
|
98
139
|
/**
|
|
99
140
|
* Connects to the MCP server using the configured transport.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI/C,OAAO,KAAK,EAAmB,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAShE,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,EAE3B,kBAAkB,EAEnB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { MastraBase } from '@mastra/core/base';
|
|
|
3
3
|
import type { MCPServerBase } from '@mastra/core/mcp';
|
|
4
4
|
import type { Tool } from '@mastra/core/tools';
|
|
5
5
|
import type { ElicitRequest, ElicitResult, ProgressNotification, Prompt, Resource, ResourceTemplate } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
-
import type { MastraMCPServerDefinition } from './client.js';
|
|
6
|
+
import type { MastraMCPServerDefinition, MCPServerAuthState } from './client.js';
|
|
7
7
|
/**
|
|
8
8
|
* Configuration options for creating an MCPClient instance.
|
|
9
9
|
*/
|
|
@@ -55,6 +55,15 @@ export declare class MCPClient extends MastraBase {
|
|
|
55
55
|
private defaultTimeout;
|
|
56
56
|
private mcpClientsById;
|
|
57
57
|
private disconnectPromise;
|
|
58
|
+
private authFlowsByServer;
|
|
59
|
+
private authCallbackServersByServer;
|
|
60
|
+
/**
|
|
61
|
+
* Per-server abort controllers for in-flight authorization flows. Created
|
|
62
|
+
* synchronously at the start of {@link runAuthorizationFlow} — before the
|
|
63
|
+
* callback server exists — so cancel/disconnect can interrupt the setup phase
|
|
64
|
+
* (discovery, registration, port binding) and not just the waitForCode wait.
|
|
65
|
+
*/
|
|
66
|
+
private authAbortControllersByServer;
|
|
58
67
|
/**
|
|
59
68
|
* Creates a new MCPClient instance for managing MCP server connections.
|
|
60
69
|
*
|
|
@@ -565,6 +574,67 @@ export declare class MCPClient extends MastraBase {
|
|
|
565
574
|
* ```
|
|
566
575
|
*/
|
|
567
576
|
reconnectServer(serverName: string): Promise<void>;
|
|
577
|
+
/**
|
|
578
|
+
* Runs the interactive OAuth authorization-code flow for a server.
|
|
579
|
+
*
|
|
580
|
+
* Requires the server to be configured with an MCPOAuthClientProvider whose
|
|
581
|
+
* redirect URL points at a loopback address. The flow:
|
|
582
|
+
*
|
|
583
|
+
* 1. Starts a loopback callback server on the redirect URL's port (falling
|
|
584
|
+
* back to the next sequential ports when it is in use)
|
|
585
|
+
* 2. Attempts a connection so the SDK runs discovery and dynamic client
|
|
586
|
+
* registration, delivering the authorization URL through the provider's
|
|
587
|
+
* `onRedirectToAuthorization` callback — the host directs the user there
|
|
588
|
+
* 3. Waits for the browser to deliver the authorization code, validates the
|
|
589
|
+
* OAuth state, exchanges the code for tokens, and reconnects
|
|
590
|
+
*
|
|
591
|
+
* Concurrent calls for the same server join the pending flow (the joiner's
|
|
592
|
+
* options are ignored — the pending flow keeps its own timeout); different
|
|
593
|
+
* servers authenticate independently. Each server needs its own provider
|
|
594
|
+
* instance: the flow pins session state on the provider, so sharing one
|
|
595
|
+
* MCPOAuthClientProvider across servers is not supported. Hosts with custom
|
|
596
|
+
* redirect handling (e.g. a web app with an HTTPS redirect URL) should
|
|
597
|
+
* drive MCPOAuthClientProvider directly instead.
|
|
598
|
+
*
|
|
599
|
+
* @param serverName - The name of the server to authenticate (must match a key in `servers`)
|
|
600
|
+
* @param options.timeoutMs - How long to wait for the browser callback (default 5 minutes)
|
|
601
|
+
* @throws {Error} If the server has no MCPOAuthClientProvider or its redirect URL is not loopback
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* ```typescript
|
|
605
|
+
* if (mcp.getServerAuthState('weatherServer') === 'needs-auth') {
|
|
606
|
+
* await mcp.authenticate('weatherServer');
|
|
607
|
+
* }
|
|
608
|
+
* ```
|
|
609
|
+
*/
|
|
610
|
+
authenticate(serverName: string, options?: {
|
|
611
|
+
timeoutMs?: number;
|
|
612
|
+
}): Promise<void>;
|
|
613
|
+
/**
|
|
614
|
+
* OAuth authorization state of a configured server.
|
|
615
|
+
*
|
|
616
|
+
* Returns `undefined` for servers without an authProvider and for servers
|
|
617
|
+
* that have not attempted a connection yet.
|
|
618
|
+
*/
|
|
619
|
+
getServerAuthState(serverName: string): MCPServerAuthState | undefined;
|
|
620
|
+
private runAuthorizationFlow;
|
|
621
|
+
/**
|
|
622
|
+
* Cancels a pending {@link authenticate} flow for a server.
|
|
623
|
+
*
|
|
624
|
+
* Tears down the loopback callback server immediately — the pending
|
|
625
|
+
* authenticate() call rejects. Useful when the user closed the browser
|
|
626
|
+
* without completing consent, which the host cannot observe.
|
|
627
|
+
*
|
|
628
|
+
* The resulting auth state depends on how far the flow had progressed: a flow
|
|
629
|
+
* cancelled after the server rejected the connection with a 401 stays in the
|
|
630
|
+
* `needs-auth` state so it can be retried right away, while a flow cancelled
|
|
631
|
+
* during the setup phase (before any connection was attempted) leaves the
|
|
632
|
+
* state unchanged — typically `undefined`.
|
|
633
|
+
*
|
|
634
|
+
* @param serverName - The name of the server whose flow to cancel
|
|
635
|
+
* @returns `true` if a pending flow was cancelled, `false` when no flow was pending
|
|
636
|
+
*/
|
|
637
|
+
cancelAuthentication(serverName: string): Promise<boolean>;
|
|
568
638
|
/**
|
|
569
639
|
* Returns instructions advertised by connected MCP servers during initialize.
|
|
570
640
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/client/configuration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,MAAM,EACN,QAAQ,EACR,gBAAgB,EACjB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/client/configuration.ts"],"names":[],"mappings":"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"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export type { LoggingLevel, LogMessage, LogHandler, MastraMCPServerDefinition, E
|
|
|
2
2
|
export * from './client.js';
|
|
3
3
|
export * from './configuration.js';
|
|
4
4
|
export * from './oauth-provider.js';
|
|
5
|
+
export * from './oauth-callback-server.js';
|
|
5
6
|
export { MCPClientServerProxy } from './server-proxy.js';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,yBAAyB,EACzB,kBAAkB,EAClB,eAAe,EACf,8BAA8B,EAC9B,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,SAAS,CAAC;AACjB,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,yBAAyB,EACzB,kBAAkB,EAClB,eAAe,EACf,8BAA8B,EAC9B,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,SAAS,CAAC;AACjB,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loopback OAuth Callback Server for MCP Client
|
|
3
|
+
*
|
|
4
|
+
* Provides a one-shot local HTTP server that captures the OAuth authorization
|
|
5
|
+
* code delivered to a loopback redirect URL (RFC 8252). Hosts use it together
|
|
6
|
+
* with MCPOAuthClientProvider to complete the authorization-code flow for
|
|
7
|
+
* OAuth-protected MCP servers.
|
|
8
|
+
*
|
|
9
|
+
* @see https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Options for creating an OAuth callback server.
|
|
13
|
+
*/
|
|
14
|
+
export interface OAuthCallbackServerOptions {
|
|
15
|
+
/**
|
|
16
|
+
* The redirect URL the authorization server will send the browser back to.
|
|
17
|
+
* Its port is the preferred port to bind; if that port is in use, the next
|
|
18
|
+
* sequential ports are tried (see getCallbackUrlCandidates). The server
|
|
19
|
+
* binds the URL's hostname — prefer the literal `127.0.0.1` over
|
|
20
|
+
* `localhost` (RFC 8252 §8.3) so the browser and server agree on the
|
|
21
|
+
* address family.
|
|
22
|
+
*
|
|
23
|
+
* @example 'http://127.0.0.1:5533/oauth/callback'
|
|
24
|
+
*/
|
|
25
|
+
redirectUrl: string | URL;
|
|
26
|
+
/**
|
|
27
|
+
* The OAuth state parameter issued for this authorization request.
|
|
28
|
+
* The state authenticates the redirect (CSRF protection per OAuth 2.1):
|
|
29
|
+
* callback requests without a matching state receive an error response and
|
|
30
|
+
* never settle the flow, so a stray local request cannot abort or spoof a
|
|
31
|
+
* pending authorization.
|
|
32
|
+
*/
|
|
33
|
+
state: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The authorization code captured from the OAuth callback.
|
|
37
|
+
*/
|
|
38
|
+
export interface OAuthCallbackResult {
|
|
39
|
+
/**
|
|
40
|
+
* The authorization code to exchange for tokens.
|
|
41
|
+
*/
|
|
42
|
+
code: string;
|
|
43
|
+
/**
|
|
44
|
+
* The state parameter echoed back by the authorization server.
|
|
45
|
+
*/
|
|
46
|
+
state: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A running loopback OAuth callback server.
|
|
50
|
+
*/
|
|
51
|
+
export interface OAuthCallbackServer {
|
|
52
|
+
/**
|
|
53
|
+
* The callback URL that is actually bound (reflects any port fallback).
|
|
54
|
+
* Use this — not the preferred redirect URL — as the redirect_uri for the
|
|
55
|
+
* authorization request.
|
|
56
|
+
*/
|
|
57
|
+
url: URL;
|
|
58
|
+
/**
|
|
59
|
+
* The port the server is listening on.
|
|
60
|
+
*/
|
|
61
|
+
port: number;
|
|
62
|
+
/**
|
|
63
|
+
* Waits for the browser to deliver the authorization code.
|
|
64
|
+
*
|
|
65
|
+
* Resolves once with the code and state from the first state-matching
|
|
66
|
+
* callback request. Rejects on timeout, on a state-matching OAuth error
|
|
67
|
+
* response (`error` / `error_description` query params), or when the
|
|
68
|
+
* server is closed before a code arrives.
|
|
69
|
+
*/
|
|
70
|
+
waitForCode(options?: {
|
|
71
|
+
timeoutMs?: number;
|
|
72
|
+
}): Promise<OAuthCallbackResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Stops the server and releases the port. Rejects any pending waitForCode.
|
|
75
|
+
* Idempotent: closing an already-closed server resolves immediately.
|
|
76
|
+
*/
|
|
77
|
+
close(): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns the candidate callback URLs for a redirect URL: the URL itself on
|
|
81
|
+
* its preferred port, followed by the sequential fallback-port variants that
|
|
82
|
+
* createOAuthCallbackServer will try when the preferred port is in use.
|
|
83
|
+
*
|
|
84
|
+
* This is the single source of the candidate list: register all of these as
|
|
85
|
+
* redirect_uris during dynamic client registration so a fallback-bound
|
|
86
|
+
* callback URL always matches a registered URI.
|
|
87
|
+
*/
|
|
88
|
+
export declare function getCallbackUrlCandidates(redirectUrl: string | URL): URL[];
|
|
89
|
+
/**
|
|
90
|
+
* Starts a one-shot loopback HTTP server that captures the OAuth
|
|
91
|
+
* authorization code.
|
|
92
|
+
*
|
|
93
|
+
* The server binds the redirect URL's hostname on its port, falling back to
|
|
94
|
+
* the next sequential ports when it is in use (see getCallbackUrlCandidates).
|
|
95
|
+
* The first state-matching request on the callback path settles the outcome;
|
|
96
|
+
* subsequent requests receive 410 Gone. Requests whose state does not match
|
|
97
|
+
* receive an error response without settling, so only the genuine redirect
|
|
98
|
+
* can complete or abort the flow. The response pages never echo the
|
|
99
|
+
* authorization code.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const callbackServer = await createOAuthCallbackServer({
|
|
104
|
+
* redirectUrl: 'http://127.0.0.1:5533/oauth/callback',
|
|
105
|
+
* state: expectedState,
|
|
106
|
+
* });
|
|
107
|
+
* try {
|
|
108
|
+
* // Direct the user to the authorization URL, then:
|
|
109
|
+
* const { code } = await callbackServer.waitForCode();
|
|
110
|
+
* await transport.finishAuth(code);
|
|
111
|
+
* } finally {
|
|
112
|
+
* await callbackServer.close();
|
|
113
|
+
* }
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function createOAuthCallbackServer(options: OAuthCallbackServerOptions): Promise<OAuthCallbackServer>;
|
|
117
|
+
//# sourceMappingURL=oauth-callback-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-callback-server.d.ts","sourceRoot":"","sources":["../../src/client/oauth-callback-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;;;;;;;OASG;IACH,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC;IAE1B;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,GAAG,EAAE,GAAG,CAAC;IAET;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;OAOG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAE5E;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,CAezE;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA8IjH"}
|
|
@@ -125,12 +125,14 @@ export interface MCPOAuthClientProviderOptions {
|
|
|
125
125
|
* ```
|
|
126
126
|
*/
|
|
127
127
|
export declare class MCPOAuthClientProvider implements OAuthClientProvider {
|
|
128
|
-
private
|
|
129
|
-
private
|
|
128
|
+
private _redirectUrl;
|
|
129
|
+
private _clientMetadata;
|
|
130
130
|
private readonly storage;
|
|
131
131
|
private readonly onRedirect?;
|
|
132
132
|
private readonly generateState;
|
|
133
133
|
private _clientInfo?;
|
|
134
|
+
private _sessionState?;
|
|
135
|
+
private _sessionRedirectUrl?;
|
|
134
136
|
constructor(options: MCPOAuthClientProviderOptions);
|
|
135
137
|
/**
|
|
136
138
|
* The URL to redirect the user agent to after authorization.
|
|
@@ -142,8 +144,42 @@ export declare class MCPOAuthClientProvider implements OAuthClientProvider {
|
|
|
142
144
|
get clientMetadata(): OAuthClientMetadata;
|
|
143
145
|
/**
|
|
144
146
|
* Returns a OAuth2 state parameter.
|
|
147
|
+
*
|
|
148
|
+
* While an authorization session is active (see beginAuthorizationSession),
|
|
149
|
+
* the pinned session state is returned so a callback server can validate
|
|
150
|
+
* the redirect against a known value.
|
|
145
151
|
*/
|
|
146
152
|
state(): Promise<string>;
|
|
153
|
+
/**
|
|
154
|
+
* Pins the OAuth state parameter for the next authorization request.
|
|
155
|
+
*
|
|
156
|
+
* Hosts driving an interactive authorization flow (e.g. MCPClient.authenticate)
|
|
157
|
+
* call this before triggering the flow so the loopback callback server knows
|
|
158
|
+
* which state value to expect. Call endAuthorizationSession once the flow settles.
|
|
159
|
+
*
|
|
160
|
+
* @returns The pinned state value, generated with the configured stateGenerator
|
|
161
|
+
*/
|
|
162
|
+
beginAuthorizationSession(): Promise<string>;
|
|
163
|
+
/**
|
|
164
|
+
* Clears the pinned authorization state (see beginAuthorizationSession) and
|
|
165
|
+
* restores the configured redirect URL if applyResolvedRedirectUrl rebased
|
|
166
|
+
* it to a fallback port during the session, so the next flow starts from
|
|
167
|
+
* the preferred port again.
|
|
168
|
+
*/
|
|
169
|
+
endAuthorizationSession(): void;
|
|
170
|
+
/**
|
|
171
|
+
* Points the provider at the callback URL that is actually bound.
|
|
172
|
+
*
|
|
173
|
+
* Loopback callback servers may bind a fallback port when the preferred one
|
|
174
|
+
* is in use. Call this before triggering authorization so the authorization
|
|
175
|
+
* request's redirect_uri matches the listening server, and so dynamic client
|
|
176
|
+
* registration registers every candidate callback URL (see
|
|
177
|
+
* getCallbackUrlCandidates) rather than only the preferred one.
|
|
178
|
+
*
|
|
179
|
+
* @param redirectUrl - The callback URL that is actually bound
|
|
180
|
+
* @param registeredRedirectUris - The redirect URIs to register during dynamic client registration
|
|
181
|
+
*/
|
|
182
|
+
applyResolvedRedirectUrl(redirectUrl: string | URL, registeredRedirectUris: (string | URL)[]): void;
|
|
147
183
|
/**
|
|
148
184
|
* Loads information about this OAuth client.
|
|
149
185
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-provider.d.ts","sourceRoot":"","sources":["../../src/client/oauth-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAElC;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEtD;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IAEnE;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3C;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,IAAI,CAA6B;IAEzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIrC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIpC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,KAAK,IAAI,IAAI;CAGd;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC;IAE1B;;;;OAIG;IACH,cAAc,EAAE,mBAAmB,CAAC;IAEpC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;IAE3C;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB;;;;;;;OAOG;IACH,yBAAyB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/D;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,sBAAuB,YAAW,mBAAmB;IAChE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"oauth-provider.d.ts","sourceRoot":"","sources":["../../src/client/oauth-provider.ts"],"names":[],"mappings":"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"}
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -64,7 +64,7 @@ export const testMcpClient = new MCPClient({
|
|
|
64
64
|
|
|
65
65
|
Visit [MCPClient](https://mastra.ai/reference/tools/mcp-client) for a full list of configuration options.
|
|
66
66
|
|
|
67
|
-
> **Authentication:** For connecting to OAuth-protected MCP servers
|
|
67
|
+
> **Authentication:** For connecting to OAuth-protected MCP servers — including completing the browser-based authorization flow with `authenticate()` — see the [OAuth Authentication](https://mastra.ai/reference/tools/mcp-client) section.
|
|
68
68
|
|
|
69
69
|
## Using `MCPClient` with an agent
|
|
70
70
|
|
|
@@ -207,6 +207,34 @@ const instructionsByServer = mcp.getServerInstructions()
|
|
|
207
207
|
console.log(instructionsByServer.db)
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
+
### `authenticate()`
|
|
211
|
+
|
|
212
|
+
Runs the interactive OAuth authorization-code flow for a server configured with an `MCPOAuthClientProvider` whose redirect URL points at a loopback address. Starts a local callback server, delivers the authorization URL through the provider's `onRedirectToAuthorization` callback, waits for the browser to return the authorization code, exchanges it for tokens, and reconnects. See [Interactive browser authentication](#interactive-browser-authentication).
|
|
213
|
+
|
|
214
|
+
The optional `timeoutMs` bounds how long the flow waits for the browser to return the authorization code before rejecting, and defaults to 5 minutes.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
async authenticate(serverName: string, options?: { timeoutMs?: number }): Promise<void>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### `getServerAuthState()`
|
|
221
|
+
|
|
222
|
+
Returns the OAuth authorization state of a configured server: `'needs-auth'` after a connection attempt was rejected with an authorization error, `'authorized'` once the server accepted the provider's credentials, or `undefined` for servers without an `authProvider` or that haven't attempted a connection yet.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
getServerAuthState(serverName: string): 'needs-auth' | 'authorized' | undefined
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### `cancelAuthentication()`
|
|
229
|
+
|
|
230
|
+
Cancels an in-progress `authenticate()` flow for a server, so an abandoned browser authorization does not leave the client waiting indefinitely. It aborts the flow (including its setup phase, before the callback server binds), closes the local callback server if one is listening, and the pending `authenticate()` call rejects. Returns `true` if a flow was cancelled, or `false` when no flow was in progress.
|
|
231
|
+
|
|
232
|
+
The resulting `getServerAuthState()` depends on how far the flow had progressed: a flow cancelled after the server rejected the connection with `401` stays at `'needs-auth'` and can be retried immediately, while a flow cancelled during the setup phase — before any connection was attempted — leaves the state unchanged (typically `undefined`).
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
async cancelAuthentication(serverName: string): Promise<boolean>
|
|
236
|
+
```
|
|
237
|
+
|
|
210
238
|
### `disconnect()`
|
|
211
239
|
|
|
212
240
|
Disconnects from all MCP servers and cleans up resources.
|
|
@@ -821,6 +849,74 @@ const client = new MCPClient({
|
|
|
821
849
|
})
|
|
822
850
|
```
|
|
823
851
|
|
|
852
|
+
Give each server its own `MCPOAuthClientProvider` instance. A provider holds per-server session and credential state during authorization, so sharing one instance across multiple servers lets their flows overwrite each other. When configuring several protected servers, construct a separate provider for each.
|
|
853
|
+
|
|
854
|
+
### Interactive browser authentication
|
|
855
|
+
|
|
856
|
+
When a server rejects a connection because authorization is required, the client records a `'needs-auth'` state instead of failing outright. Calling `authenticate()` then completes the flow end to end: it starts a one-shot callback server on the provider's loopback redirect URL (falling back to the next sequential ports when it is in use), lets the SDK run discovery and dynamic client registration, delivers the authorization URL through `onRedirectToAuthorization` — open it in the user's browser — and finishes the token exchange once the browser returns the authorization code:
|
|
857
|
+
|
|
858
|
+
```typescript
|
|
859
|
+
import { MCPClient, MCPOAuthClientProvider } from '@mastra/mcp'
|
|
860
|
+
|
|
861
|
+
const oauthProvider = new MCPOAuthClientProvider({
|
|
862
|
+
redirectUrl: 'http://127.0.0.1:5533/oauth/callback',
|
|
863
|
+
clientMetadata: {
|
|
864
|
+
redirect_uris: ['http://127.0.0.1:5533/oauth/callback'],
|
|
865
|
+
client_name: 'My MCP Client',
|
|
866
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
867
|
+
response_types: ['code'],
|
|
868
|
+
},
|
|
869
|
+
onRedirectToAuthorization: url => {
|
|
870
|
+
// Open the user's browser at the consent page
|
|
871
|
+
console.log(`Please visit: ${url}`)
|
|
872
|
+
},
|
|
873
|
+
})
|
|
874
|
+
|
|
875
|
+
const mcp = new MCPClient({
|
|
876
|
+
servers: {
|
|
877
|
+
protectedServer: {
|
|
878
|
+
url: new URL('https://mcp.example.com/mcp'),
|
|
879
|
+
authProvider: oauthProvider,
|
|
880
|
+
},
|
|
881
|
+
},
|
|
882
|
+
})
|
|
883
|
+
|
|
884
|
+
try {
|
|
885
|
+
await mcp.listTools()
|
|
886
|
+
} catch {
|
|
887
|
+
if (mcp.getServerAuthState('protectedServer') === 'needs-auth') {
|
|
888
|
+
await mcp.authenticate('protectedServer')
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
Concurrent `authenticate()` calls for the same server join the pending flow; different servers authenticate independently. With valid stored tokens the call simply reconnects without opening a browser.
|
|
894
|
+
|
|
895
|
+
Hosts that drive the flow themselves can capture the authorization code with the exported `createOAuthCallbackServer` helper, which binds a one-shot loopback server, validates the OAuth `state` parameter, and resolves with the code. It creates a plain HTTP server, so it is only for local loopback redirects. Web applications that use an HTTPS redirect URL must host their own callback endpoint and drive the provider directly rather than using this helper:
|
|
896
|
+
|
|
897
|
+
```typescript
|
|
898
|
+
import { createOAuthCallbackServer, getCallbackUrlCandidates } from '@mastra/mcp'
|
|
899
|
+
|
|
900
|
+
// getCallbackUrlCandidates() lists every URL the helper may bind, so register
|
|
901
|
+
// all of them as redirect_uris during client registration to cover port fallback.
|
|
902
|
+
const redirectUris = getCallbackUrlCandidates('http://127.0.0.1:5533/oauth/callback').map(url =>
|
|
903
|
+
url.toString(),
|
|
904
|
+
)
|
|
905
|
+
|
|
906
|
+
const server = await createOAuthCallbackServer({
|
|
907
|
+
redirectUrl: 'http://127.0.0.1:5533/oauth/callback',
|
|
908
|
+
state: expectedState,
|
|
909
|
+
})
|
|
910
|
+
|
|
911
|
+
// server.url reflects the port actually bound — use it as the redirect_uri.
|
|
912
|
+
try {
|
|
913
|
+
const { code } = await server.waitForCode()
|
|
914
|
+
// Exchange the code here.
|
|
915
|
+
} finally {
|
|
916
|
+
await server.close()
|
|
917
|
+
}
|
|
918
|
+
```
|
|
919
|
+
|
|
824
920
|
### Quick Token Provider
|
|
825
921
|
|
|
826
922
|
For testing or when you already have a valid access token:
|