Skip to content

Commit 514f549

Browse files
authored
Merge branch 'main' into server-authorization-proxy
2 parents b90192a + 0fa2397 commit 514f549

File tree

6 files changed

+97
-2
lines changed

6 files changed

+97
-2
lines changed

CLAUDE.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# MCP TypeScript SDK Guide
2+
3+
## Build & Test Commands
4+
```
5+
npm run build # Build ESM and CJS versions
6+
npm run lint # Run ESLint
7+
npm test # Run all tests
8+
npx jest path/to/file.test.ts # Run specific test file
9+
npx jest -t "test name" # Run tests matching pattern
10+
```
11+
12+
## Code Style Guidelines
13+
- **TypeScript**: Strict type checking, ES modules, explicit return types
14+
- **Naming**: PascalCase for classes/types, camelCase for functions/variables
15+
- **Files**: Lowercase with hyphens, test files with `.test.ts` suffix
16+
- **Imports**: ES module style, include `.js` extension, group imports logically
17+
- **Error Handling**: Use TypeScript's strict mode, explicit error checking in tests
18+
- **Formatting**: 2-space indentation, semicolons required, single quotes preferred
19+
- **Testing**: Co-locate tests with source files, use descriptive test names
20+
- **Comments**: JSDoc for public APIs, inline comments for complex logic
21+
22+
## Project Structure
23+
- `/src`: Source code with client, server, and shared modules
24+
- Tests alongside source files with `.test.ts` suffix
25+
- Node.js >= 18 required

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.6.0",
3+
"version": "1.7.0",
44
"description": "Model Context Protocol implementation for TypeScript",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",

src/inMemory.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export class InMemoryTransport implements Transport {
1111
onclose?: () => void;
1212
onerror?: (error: Error) => void;
1313
onmessage?: (message: JSONRPCMessage) => void;
14+
sessionId?: string;
1415

1516
/**
1617
* Creates a pair of linked in-memory transports that can communicate with each other. One should be passed to a Client and one to a Server.

src/server/mcp.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,59 @@ describe("tool()", () => {
323323
mcpServer.tool("tool2", () => ({ content: [] }));
324324
});
325325

326+
test("should pass sessionId to tool callback via RequestHandlerExtra", async () => {
327+
const mcpServer = new McpServer({
328+
name: "test server",
329+
version: "1.0",
330+
});
331+
332+
const client = new Client(
333+
{
334+
name: "test client",
335+
version: "1.0",
336+
},
337+
{
338+
capabilities: {
339+
tools: {},
340+
},
341+
},
342+
);
343+
344+
let receivedSessionId: string | undefined;
345+
mcpServer.tool("test-tool", async (extra) => {
346+
receivedSessionId = extra.sessionId;
347+
return {
348+
content: [
349+
{
350+
type: "text",
351+
text: "Test response",
352+
},
353+
],
354+
};
355+
});
356+
357+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
358+
// Set a test sessionId on the server transport
359+
serverTransport.sessionId = "test-session-123";
360+
361+
await Promise.all([
362+
client.connect(clientTransport),
363+
mcpServer.server.connect(serverTransport),
364+
]);
365+
366+
await client.request(
367+
{
368+
method: "tools/call",
369+
params: {
370+
name: "test-tool",
371+
},
372+
},
373+
CallToolResultSchema,
374+
);
375+
376+
expect(receivedSessionId).toBe("test-session-123");
377+
});
378+
326379
test("should allow client to call server tools", async () => {
327380
const mcpServer = new McpServer({
328381
name: "test server",

src/shared/protocol.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ export type RequestHandlerExtra = {
8888
* An abort signal used to communicate if the request was cancelled from the sender's side.
8989
*/
9090
signal: AbortSignal;
91+
92+
/**
93+
* The session ID from the transport, if available.
94+
*/
95+
sessionId?: string;
9196
};
9297

9398
/**
@@ -307,9 +312,15 @@ export abstract class Protocol<
307312
const abortController = new AbortController();
308313
this._requestHandlerAbortControllers.set(request.id, abortController);
309314

315+
// Create extra object with both abort signal and sessionId from transport
316+
const extra: RequestHandlerExtra = {
317+
signal: abortController.signal,
318+
sessionId: this._transport?.sessionId,
319+
};
320+
310321
// Starting with Promise.resolve() puts any synchronous errors into the monad as well.
311322
Promise.resolve()
312-
.then(() => handler(request, { signal: abortController.signal }))
323+
.then(() => handler(request, extra))
313324
.then(
314325
(result) => {
315326
if (abortController.signal.aborted) {

src/shared/transport.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,9 @@ export interface Transport {
4141
* Callback for when a message (request or response) is received over the connection.
4242
*/
4343
onmessage?: (message: JSONRPCMessage) => void;
44+
45+
/**
46+
* The session ID generated for this connection.
47+
*/
48+
sessionId?: string;
4449
}

0 commit comments

Comments
 (0)