@mcp-z/client 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/cjs/auth/discovery-fetch.d.cts +22 -2
- package/dist/cjs/auth/discovery-fetch.d.ts +22 -2
- package/dist/cjs/auth/discovery-fetch.js +440 -124
- package/dist/cjs/auth/discovery-fetch.js.map +1 -1
- package/dist/cjs/connection/connect-client.d.cts +11 -0
- package/dist/cjs/connection/connect-client.d.ts +11 -0
- package/dist/cjs/connection/connect-client.js +12 -7
- package/dist/cjs/connection/connect-client.js.map +1 -1
- package/dist/cjs/index.d.cts +2 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +8 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/auth/discovery-fetch.d.ts +22 -2
- package/dist/esm/auth/discovery-fetch.js +234 -54
- package/dist/esm/auth/discovery-fetch.js.map +1 -1
- package/dist/esm/connection/connect-client.d.ts +11 -0
- package/dist/esm/connection/connect-client.js +20 -6
- package/dist/esm/connection/connect-client.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +4 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -156,6 +156,28 @@ const client = await registry.connect('todoist', {
|
|
|
156
156
|
});
|
|
157
157
|
```
|
|
158
158
|
|
|
159
|
+
## Protocol version negotiation
|
|
160
|
+
|
|
161
|
+
By default a connect performs the plain 2025 MCP connect sequence. Pass `versionNegotiation` to negotiate the protocol revision instead:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
// Probe the server first; connect at the newest revision it offers,
|
|
165
|
+
// falling back to the 2025 sequence when it cannot serve the modern era
|
|
166
|
+
const client = await registry.connect('modern-server', {
|
|
167
|
+
versionNegotiation: { mode: 'auto' }
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Require the 2026-07-28 revision; a server that cannot serve it fails
|
|
171
|
+
// the connect with SdkErrorCode.EraNegotiationFailed
|
|
172
|
+
const pinned = await registry.connect('strict-server', {
|
|
173
|
+
versionNegotiation: { mode: { pin: '2026-07-28' } }
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
After connecting, `client.getProtocolEra()` returns `'modern'` or `'legacy'` and `client.getNegotiatedProtocolVersion()` the revision the server settled on.
|
|
178
|
+
|
|
179
|
+
Note: with `mode: 'auto'` against a stdio server, a legacy server that never answers the `server/discover` probe costs the full request timeout (60s) before the client falls back to the 2025 sequence. The probe ends fast when the server answers it at all — with any reply, even a "method not found" error.
|
|
180
|
+
|
|
159
181
|
## Requirements
|
|
160
182
|
|
|
161
183
|
- Node.js >= 22
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
export declare class DiscoveryFetchError extends Error {
|
|
2
2
|
constructor(message: string);
|
|
3
3
|
}
|
|
4
|
+
type LookupRecord = {
|
|
5
|
+
address: string;
|
|
6
|
+
family: number;
|
|
7
|
+
};
|
|
8
|
+
/** DNS implementation, injectable for deterministic tests. Same contract as `dns.lookup` with `{ all: true, verbatim: true }`. */
|
|
9
|
+
type Lookup = (hostname: string, options: {
|
|
10
|
+
all: true;
|
|
11
|
+
verbatim: true;
|
|
12
|
+
}, callback: (error: NodeJS.ErrnoException | null, addresses: LookupRecord[]) => void) => void;
|
|
4
13
|
/**
|
|
5
14
|
* True if `rawUrl`'s host is loopback, used to decide `allowLoopback` grants
|
|
6
15
|
* from the URL the caller configured, not remote-supplied data. Fails closed on an unparseable URL.
|
|
@@ -13,15 +22,25 @@ export interface DiscoveryFetchOptions {
|
|
|
13
22
|
*/
|
|
14
23
|
allowLoopback?: boolean;
|
|
15
24
|
/**
|
|
16
|
-
* Per-
|
|
17
|
-
* overridable so tests can bound slow-failure cases.
|
|
25
|
+
* Per-hop timeout in ms, applied to both the DNS resolution and the request.
|
|
26
|
+
* Defaults to `DEFAULT_TIMEOUT_MS`; overridable so tests can bound slow-failure cases.
|
|
18
27
|
*/
|
|
19
28
|
timeoutMs?: number;
|
|
29
|
+
/**
|
|
30
|
+
* DNS implementation used for the pre-request resolution, injectable for
|
|
31
|
+
* deterministic tests. Defaults to `dns.lookup`.
|
|
32
|
+
*/
|
|
33
|
+
lookup?: Lookup;
|
|
20
34
|
}
|
|
21
35
|
/**
|
|
22
36
|
* Fetches an OAuth-discovery URL with SSRF mitigations applied to the
|
|
23
37
|
* initial URL and every redirect hop; redirects are validated, not auto-followed.
|
|
24
38
|
*
|
|
39
|
+
* The hostname is resolved once, every returned address is validated, and the
|
|
40
|
+
* validated set is pinned into the request through a custom `lookup`, so the
|
|
41
|
+
* request cannot resolve the hostname a second time and cannot be steered to
|
|
42
|
+
* a different address by a DNS-rebinding answer.
|
|
43
|
+
*
|
|
25
44
|
* @param rawUrl - URL to fetch; may be remote-server-supplied (the threat this guards against).
|
|
26
45
|
* @param init - Standard fetch options; `redirect` is always forced to `'manual'`.
|
|
27
46
|
* @param context - Short label used only in error messages, never echoing the URL.
|
|
@@ -33,3 +52,4 @@ export declare function discoveryFetch(rawUrl: string, init?: RequestInit, conte
|
|
|
33
52
|
* while reading (not after buffering the whole thing).
|
|
34
53
|
*/
|
|
35
54
|
export declare function readDiscoveryJson<T>(response: Response, context: string): Promise<T>;
|
|
55
|
+
export {};
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
export declare class DiscoveryFetchError extends Error {
|
|
2
2
|
constructor(message: string);
|
|
3
3
|
}
|
|
4
|
+
type LookupRecord = {
|
|
5
|
+
address: string;
|
|
6
|
+
family: number;
|
|
7
|
+
};
|
|
8
|
+
/** DNS implementation, injectable for deterministic tests. Same contract as `dns.lookup` with `{ all: true, verbatim: true }`. */
|
|
9
|
+
type Lookup = (hostname: string, options: {
|
|
10
|
+
all: true;
|
|
11
|
+
verbatim: true;
|
|
12
|
+
}, callback: (error: NodeJS.ErrnoException | null, addresses: LookupRecord[]) => void) => void;
|
|
4
13
|
/**
|
|
5
14
|
* True if `rawUrl`'s host is loopback, used to decide `allowLoopback` grants
|
|
6
15
|
* from the URL the caller configured, not remote-supplied data. Fails closed on an unparseable URL.
|
|
@@ -13,15 +22,25 @@ export interface DiscoveryFetchOptions {
|
|
|
13
22
|
*/
|
|
14
23
|
allowLoopback?: boolean;
|
|
15
24
|
/**
|
|
16
|
-
* Per-
|
|
17
|
-
* overridable so tests can bound slow-failure cases.
|
|
25
|
+
* Per-hop timeout in ms, applied to both the DNS resolution and the request.
|
|
26
|
+
* Defaults to `DEFAULT_TIMEOUT_MS`; overridable so tests can bound slow-failure cases.
|
|
18
27
|
*/
|
|
19
28
|
timeoutMs?: number;
|
|
29
|
+
/**
|
|
30
|
+
* DNS implementation used for the pre-request resolution, injectable for
|
|
31
|
+
* deterministic tests. Defaults to `dns.lookup`.
|
|
32
|
+
*/
|
|
33
|
+
lookup?: Lookup;
|
|
20
34
|
}
|
|
21
35
|
/**
|
|
22
36
|
* Fetches an OAuth-discovery URL with SSRF mitigations applied to the
|
|
23
37
|
* initial URL and every redirect hop; redirects are validated, not auto-followed.
|
|
24
38
|
*
|
|
39
|
+
* The hostname is resolved once, every returned address is validated, and the
|
|
40
|
+
* validated set is pinned into the request through a custom `lookup`, so the
|
|
41
|
+
* request cannot resolve the hostname a second time and cannot be steered to
|
|
42
|
+
* a different address by a DNS-rebinding answer.
|
|
43
|
+
*
|
|
25
44
|
* @param rawUrl - URL to fetch; may be remote-server-supplied (the threat this guards against).
|
|
26
45
|
* @param init - Standard fetch options; `redirect` is always forced to `'manual'`.
|
|
27
46
|
* @param context - Short label used only in error messages, never echoing the URL.
|
|
@@ -33,3 +52,4 @@ export declare function discoveryFetch(rawUrl: string, init?: RequestInit, conte
|
|
|
33
52
|
* while reading (not after buffering the whole thing).
|
|
34
53
|
*/
|
|
35
54
|
export declare function readDiscoveryJson<T>(response: Response, context: string): Promise<T>;
|
|
55
|
+
export {};
|