Merge branch 'main' into server-authorization-proxy
This commit is contained in:
commit
514f5493b0
6 changed files with 97 additions and 2 deletions
25
CLAUDE.md
Normal file
25
CLAUDE.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# MCP TypeScript SDK Guide
|
||||
|
||||
## Build & Test Commands
|
||||
```
|
||||
npm run build # Build ESM and CJS versions
|
||||
npm run lint # Run ESLint
|
||||
npm test # Run all tests
|
||||
npx jest path/to/file.test.ts # Run specific test file
|
||||
npx jest -t "test name" # Run tests matching pattern
|
||||
```
|
||||
|
||||
## Code Style Guidelines
|
||||
- **TypeScript**: Strict type checking, ES modules, explicit return types
|
||||
- **Naming**: PascalCase for classes/types, camelCase for functions/variables
|
||||
- **Files**: Lowercase with hyphens, test files with `.test.ts` suffix
|
||||
- **Imports**: ES module style, include `.js` extension, group imports logically
|
||||
- **Error Handling**: Use TypeScript's strict mode, explicit error checking in tests
|
||||
- **Formatting**: 2-space indentation, semicolons required, single quotes preferred
|
||||
- **Testing**: Co-locate tests with source files, use descriptive test names
|
||||
- **Comments**: JSDoc for public APIs, inline comments for complex logic
|
||||
|
||||
## Project Structure
|
||||
- `/src`: Source code with client, server, and shared modules
|
||||
- Tests alongside source files with `.test.ts` suffix
|
||||
- Node.js >= 18 required
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@modelcontextprotocol/sdk",
|
||||
"version": "1.6.0",
|
||||
"version": "1.7.0",
|
||||
"description": "Model Context Protocol implementation for TypeScript",
|
||||
"license": "MIT",
|
||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export class InMemoryTransport implements Transport {
|
|||
onclose?: () => void;
|
||||
onerror?: (error: Error) => void;
|
||||
onmessage?: (message: JSONRPCMessage) => void;
|
||||
sessionId?: string;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
|
|
|||
|
|
@ -323,6 +323,59 @@ describe("tool()", () => {
|
|||
mcpServer.tool("tool2", () => ({ content: [] }));
|
||||
});
|
||||
|
||||
test("should pass sessionId to tool callback via RequestHandlerExtra", async () => {
|
||||
const mcpServer = new McpServer({
|
||||
name: "test server",
|
||||
version: "1.0",
|
||||
});
|
||||
|
||||
const client = new Client(
|
||||
{
|
||||
name: "test client",
|
||||
version: "1.0",
|
||||
},
|
||||
{
|
||||
capabilities: {
|
||||
tools: {},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
let receivedSessionId: string | undefined;
|
||||
mcpServer.tool("test-tool", async (extra) => {
|
||||
receivedSessionId = extra.sessionId;
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "Test response",
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
||||
// Set a test sessionId on the server transport
|
||||
serverTransport.sessionId = "test-session-123";
|
||||
|
||||
await Promise.all([
|
||||
client.connect(clientTransport),
|
||||
mcpServer.server.connect(serverTransport),
|
||||
]);
|
||||
|
||||
await client.request(
|
||||
{
|
||||
method: "tools/call",
|
||||
params: {
|
||||
name: "test-tool",
|
||||
},
|
||||
},
|
||||
CallToolResultSchema,
|
||||
);
|
||||
|
||||
expect(receivedSessionId).toBe("test-session-123");
|
||||
});
|
||||
|
||||
test("should allow client to call server tools", async () => {
|
||||
const mcpServer = new McpServer({
|
||||
name: "test server",
|
||||
|
|
|
|||
|
|
@ -88,6 +88,11 @@ export type RequestHandlerExtra = {
|
|||
* An abort signal used to communicate if the request was cancelled from the sender's side.
|
||||
*/
|
||||
signal: AbortSignal;
|
||||
|
||||
/**
|
||||
* The session ID from the transport, if available.
|
||||
*/
|
||||
sessionId?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -307,9 +312,15 @@ export abstract class Protocol<
|
|||
const abortController = new AbortController();
|
||||
this._requestHandlerAbortControllers.set(request.id, abortController);
|
||||
|
||||
// Create extra object with both abort signal and sessionId from transport
|
||||
const extra: RequestHandlerExtra = {
|
||||
signal: abortController.signal,
|
||||
sessionId: this._transport?.sessionId,
|
||||
};
|
||||
|
||||
// Starting with Promise.resolve() puts any synchronous errors into the monad as well.
|
||||
Promise.resolve()
|
||||
.then(() => handler(request, { signal: abortController.signal }))
|
||||
.then(() => handler(request, extra))
|
||||
.then(
|
||||
(result) => {
|
||||
if (abortController.signal.aborted) {
|
||||
|
|
|
|||
|
|
@ -41,4 +41,9 @@ export interface Transport {
|
|||
* Callback for when a message (request or response) is received over the connection.
|
||||
*/
|
||||
onmessage?: (message: JSONRPCMessage) => void;
|
||||
|
||||
/**
|
||||
* The session ID generated for this connection.
|
||||
*/
|
||||
sessionId?: string;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue