Set Mcp-Protocol-Version in client requests after init, and warn when it doesn't match negotiated version (it SHOULD match)

This commit is contained in:
Olivier Chafik 2025-06-10 14:07:10 +01:00
commit 84971c83ea
No known key found for this signature in database
3 changed files with 243 additions and 19 deletions

View file

@ -165,6 +165,8 @@ export class Client<
this._serverCapabilities = result.capabilities;
this._serverVersion = result.serverInfo;
// HTTP transports must set the protocol version in each header after initialization.
transport.protocolVersion = result.protocolVersion;
this._instructions = result.instructions;

View file

@ -62,6 +62,7 @@ export class SSEClientTransport implements Transport {
private _eventSourceInit?: EventSourceInit;
private _requestInit?: RequestInit;
private _authProvider?: OAuthClientProvider;
protocolVersion?: string;
onclose?: () => void;
onerror?: (error: Error) => void;
@ -99,13 +100,18 @@ export class SSEClientTransport implements Transport {
}
private async _commonHeaders(): Promise<HeadersInit> {
const headers: HeadersInit = { ...this._requestInit?.headers };
const headers = {
...this._requestInit?.headers,
} as HeadersInit & Record<string, string>;
if (this._authProvider) {
const tokens = await this._authProvider.tokens();
if (tokens) {
(headers as Record<string, string>)["Authorization"] = `Bearer ${tokens.access_token}`;
headers["Authorization"] = `Bearer ${tokens.access_token}`;
}
}
if (this.protocolVersion) {
headers["mcp-protocol-version"] = this.protocolVersion;
}
return headers;
}
@ -214,7 +220,9 @@ export class SSEClientTransport implements Transport {
try {
const commonHeaders = await this._commonHeaders();
const headers = new Headers({ ...commonHeaders, ...this._requestInit?.headers });
// Note: this._requestInit?.headers already set in _commonHeaders
// const headers = new Headers({ ...commonHeaders, ...this._requestInit?.headers });
const headers = new Headers(commonHeaders);
headers.set("content-type", "application/json");
const init = {
...this._requestInit,

View file

@ -124,6 +124,7 @@ export class StreamableHTTPClientTransport implements Transport {
private _authProvider?: OAuthClientProvider;
private _sessionId?: string;
private _reconnectionOptions: StreamableHTTPReconnectionOptions;
protocolVersion?: string;
onclose?: () => void;
onerror?: (error: Error) => void;
@ -162,7 +163,7 @@ export class StreamableHTTPClientTransport implements Transport {
}
private async _commonHeaders(): Promise<Headers> {
const headers: HeadersInit = {};
const headers: HeadersInit & Record<string, string> = {};
if (this._authProvider) {
const tokens = await this._authProvider.tokens();
if (tokens) {
@ -173,6 +174,9 @@ export class StreamableHTTPClientTransport implements Transport {
if (this._sessionId) {
headers["mcp-session-id"] = this._sessionId;
}
if (this.protocolVersion != null) {
headers["mcp-protocol-version"] = this.protocolVersion;
}
return new Headers(
{ ...headers, ...this._requestInit?.headers }