Skip to content

Commit 17897b8

Browse files
authored
Merge branch 'main' into dhodun/add-streamable-http-comments
2 parents eefdcf5 + 2e119aa commit 17897b8

24 files changed

+3743
-487
lines changed

README.md

Lines changed: 343 additions & 25 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modelcontextprotocol/sdk",
3-
"version": "1.12.0",
3+
"version": "1.12.3",
44
"description": "Model Context Protocol implementation for TypeScript",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",

src/client/index.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
ListToolsRequestSchema,
1515
CallToolRequestSchema,
1616
CreateMessageRequestSchema,
17+
ElicitRequestSchema,
1718
ListRootsRequestSchema,
1819
ErrorCode,
1920
} from "../types.js";
@@ -597,6 +598,43 @@ test("should only allow setRequestHandler for declared capabilities", () => {
597598
}).toThrow("Client does not support roots capability");
598599
});
599600

601+
test("should allow setRequestHandler for declared elicitation capability", () => {
602+
const client = new Client(
603+
{
604+
name: "test-client",
605+
version: "1.0.0",
606+
},
607+
{
608+
capabilities: {
609+
elicitation: {},
610+
},
611+
},
612+
);
613+
614+
// This should work because elicitation is a declared capability
615+
expect(() => {
616+
client.setRequestHandler(ElicitRequestSchema, () => ({
617+
action: "accept",
618+
content: {
619+
username: "test-user",
620+
confirmed: true,
621+
},
622+
}));
623+
}).not.toThrow();
624+
625+
// This should throw because sampling is not a declared capability
626+
expect(() => {
627+
client.setRequestHandler(CreateMessageRequestSchema, () => ({
628+
model: "test-model",
629+
role: "assistant",
630+
content: {
631+
type: "text",
632+
text: "Test response",
633+
},
634+
}));
635+
}).toThrow("Client does not support sampling capability");
636+
});
637+
600638
/***
601639
* Test: Type Checking
602640
* Test that custom request/notification/result schemas can be used with the Client class.

src/client/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ export class Client<
165165

166166
this._serverCapabilities = result.capabilities;
167167
this._serverVersion = result.serverInfo;
168+
// HTTP transports must set the protocol version in each header after initialization.
169+
if (transport.setProtocolVersion) {
170+
transport.setProtocolVersion(result.protocolVersion);
171+
}
168172

169173
this._instructions = result.instructions;
170174

@@ -303,6 +307,14 @@ export class Client<
303307
}
304308
break;
305309

310+
case "elicitation/create":
311+
if (!this._capabilities.elicitation) {
312+
throw new Error(
313+
`Client does not support elicitation capability (required for ${method})`,
314+
);
315+
}
316+
break;
317+
306318
case "roots/list":
307319
if (!this._capabilities.roots) {
308320
throw new Error(

src/client/sse.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export class SSEClientTransport implements Transport {
6262
private _eventSourceInit?: EventSourceInit;
6363
private _requestInit?: RequestInit;
6464
private _authProvider?: OAuthClientProvider;
65+
private _protocolVersion?: string;
6566

6667
onclose?: () => void;
6768
onerror?: (error: Error) => void;
@@ -99,13 +100,18 @@ export class SSEClientTransport implements Transport {
99100
}
100101

101102
private async _commonHeaders(): Promise<HeadersInit> {
102-
const headers: HeadersInit = {};
103+
const headers = {
104+
...this._requestInit?.headers,
105+
} as HeadersInit & Record<string, string>;
103106
if (this._authProvider) {
104107
const tokens = await this._authProvider.tokens();
105108
if (tokens) {
106109
headers["Authorization"] = `Bearer ${tokens.access_token}`;
107110
}
108111
}
112+
if (this._protocolVersion) {
113+
headers["mcp-protocol-version"] = this._protocolVersion;
114+
}
109115

110116
return headers;
111117
}
@@ -214,7 +220,7 @@ export class SSEClientTransport implements Transport {
214220

215221
try {
216222
const commonHeaders = await this._commonHeaders();
217-
const headers = new Headers({ ...commonHeaders, ...this._requestInit?.headers });
223+
const headers = new Headers(commonHeaders);
218224
headers.set("content-type", "application/json");
219225
const init = {
220226
...this._requestInit,
@@ -249,4 +255,8 @@ export class SSEClientTransport implements Transport {
249255
throw error;
250256
}
251257
}
258+
259+
setProtocolVersion(version: string): void {
260+
this._protocolVersion = version;
261+
}
252262
}

src/client/streamableHttp.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export class StreamableHTTPClientTransport implements Transport {
124124
private _authProvider?: OAuthClientProvider;
125125
private _sessionId?: string;
126126
private _reconnectionOptions: StreamableHTTPReconnectionOptions;
127+
private _protocolVersion?: string;
127128

128129
onclose?: () => void;
129130
onerror?: (error: Error) => void;
@@ -162,7 +163,7 @@ export class StreamableHTTPClientTransport implements Transport {
162163
}
163164

164165
private async _commonHeaders(): Promise<Headers> {
165-
const headers: HeadersInit = {};
166+
const headers: HeadersInit & Record<string, string> = {};
166167
if (this._authProvider) {
167168
const tokens = await this._authProvider.tokens();
168169
if (tokens) {
@@ -173,6 +174,9 @@ export class StreamableHTTPClientTransport implements Transport {
173174
if (this._sessionId) {
174175
headers["mcp-session-id"] = this._sessionId;
175176
}
177+
if (this._protocolVersion) {
178+
headers["mcp-protocol-version"] = this._protocolVersion;
179+
}
176180

177181
return new Headers(
178182
{ ...headers, ...this._requestInit?.headers }
@@ -516,4 +520,11 @@ export class StreamableHTTPClientTransport implements Transport {
516520
throw error;
517521
}
518522
}
523+
524+
setProtocolVersion(version: string): void {
525+
this._protocolVersion = version;
526+
}
527+
get protocolVersion(): string | undefined {
528+
return this._protocolVersion;
529+
}
519530
}

0 commit comments

Comments
 (0)