Merge branch 'main' into fix/module-format
This commit is contained in:
commit
0e76d4469e
5 changed files with 92 additions and 14 deletions
|
|
@ -24,6 +24,10 @@ npm install @modelcontextprotocol/sdk
|
|||
```typescript
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
||||
import {
|
||||
ListResourcesRequestSchema,
|
||||
ReadResourceRequestSchema,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
|
||||
const transport = new StdioClientTransport({
|
||||
command: "path/to/server",
|
||||
|
|
@ -61,6 +65,10 @@ const resourceContent = await client.request(
|
|||
```typescript
|
||||
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import {
|
||||
ListResourcesRequestSchema,
|
||||
ReadResourceRequestSchema,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
|
||||
const server = new Server({
|
||||
name: "example-server",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@modelcontextprotocol/sdk",
|
||||
"version": "1.0.4",
|
||||
"version": "1.1.0",
|
||||
"description": "Model Context Protocol implementation for TypeScript",
|
||||
"license": "MIT",
|
||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||
|
|
|
|||
|
|
@ -12,13 +12,17 @@ export class SSEClientTransport implements Transport {
|
|||
private _endpoint?: URL;
|
||||
private _abortController?: AbortController;
|
||||
private _url: URL;
|
||||
private _eventSourceInit?: EventSourceInit;
|
||||
private _requestInit?: RequestInit;
|
||||
|
||||
onclose?: () => void;
|
||||
onerror?: (error: Error) => void;
|
||||
onmessage?: (message: JSONRPCMessage) => void;
|
||||
|
||||
constructor(url: URL) {
|
||||
constructor(url: URL, opts?: { eventSourceInit?: EventSourceInit, requestInit?: RequestInit }) {
|
||||
this._url = url;
|
||||
this._eventSourceInit = opts?.eventSourceInit;
|
||||
this._requestInit = opts?.requestInit;
|
||||
}
|
||||
|
||||
start(): Promise<void> {
|
||||
|
|
@ -29,7 +33,7 @@ export class SSEClientTransport implements Transport {
|
|||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this._eventSource = new EventSource(this._url.href);
|
||||
this._eventSource = new EventSource(this._url.href, this._eventSourceInit);
|
||||
this._abortController = new AbortController();
|
||||
|
||||
this._eventSource.onerror = (event) => {
|
||||
|
|
@ -90,14 +94,17 @@ export class SSEClientTransport implements Transport {
|
|||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(this._endpoint, {
|
||||
const headers = new Headers(this._requestInit?.headers);
|
||||
headers.set("content-type", "application/json");
|
||||
const init = {
|
||||
...this._requestInit,
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
headers,
|
||||
body: JSON.stringify(message),
|
||||
signal: this._abortController?.signal,
|
||||
});
|
||||
signal: this._abortController?.signal
|
||||
};
|
||||
|
||||
const response = await fetch(this._endpoint, init);
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text().catch(() => null);
|
||||
|
|
|
|||
63
src/shared/protocol.test.ts
Normal file
63
src/shared/protocol.test.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { Protocol } from "./protocol.js";
|
||||
import { Transport } from "./transport.js";
|
||||
import {
|
||||
McpError,
|
||||
ErrorCode,
|
||||
Request,
|
||||
Result,
|
||||
Notification,
|
||||
} from "../types.js";
|
||||
import { ZodType, z } from "zod";
|
||||
|
||||
// Mock Transport class
|
||||
class MockTransport implements Transport {
|
||||
onclose?: () => void;
|
||||
onerror?: (error: Error) => void;
|
||||
onmessage?: (message: unknown) => void;
|
||||
|
||||
async start(): Promise<void> {}
|
||||
async close(): Promise<void> {
|
||||
this.onclose?.();
|
||||
}
|
||||
async send(_message: unknown): Promise<void> {}
|
||||
}
|
||||
|
||||
describe("protocol tests", () => {
|
||||
let protocol: Protocol<Request, Notification, Result>;
|
||||
let transport: MockTransport;
|
||||
|
||||
beforeEach(() => {
|
||||
transport = new MockTransport();
|
||||
protocol = new (class extends Protocol<Request, Notification, Result> {
|
||||
protected assertCapabilityForMethod(): void {}
|
||||
protected assertNotificationCapability(): void {}
|
||||
protected assertRequestHandlerCapability(): void {}
|
||||
})();
|
||||
});
|
||||
|
||||
test("should throw a timeout error if the request exceeds the timeout", async () => {
|
||||
await protocol.connect(transport);
|
||||
const request = { method: "example", params: {} };
|
||||
try {
|
||||
const mockSchema: ZodType<{ result: string }> = z.object({
|
||||
result: z.string(),
|
||||
});
|
||||
await protocol.request(request, mockSchema, {
|
||||
timeout: 0,
|
||||
});
|
||||
} catch (error) {
|
||||
expect(error).toBeInstanceOf(McpError);
|
||||
if (error instanceof McpError) {
|
||||
expect(error.code).toBe(ErrorCode.RequestTimeout);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("should invoke onclose when the connection is closed", async () => {
|
||||
const oncloseMock = jest.fn();
|
||||
protocol.onclose = oncloseMock;
|
||||
await protocol.connect(transport);
|
||||
await transport.close();
|
||||
expect(oncloseMock).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
10
src/types.ts
10
src/types.ts
|
|
@ -100,13 +100,13 @@ export const JSONRPCResponseSchema = z
|
|||
.strict();
|
||||
|
||||
/**
|
||||
* An incomplete set of error codes that may appear in JSON-RPC responses.
|
||||
* Error codes defined by the JSON-RPC specification.
|
||||
*/
|
||||
export enum ErrorCode {
|
||||
// SDK error codes
|
||||
ConnectionClosed = -1,
|
||||
RequestTimeout = -2,
|
||||
|
||||
ConnectionClosed = -32000,
|
||||
RequestTimeout = -32001,
|
||||
|
||||
// Standard JSON-RPC error codes
|
||||
ParseError = -32700,
|
||||
InvalidRequest = -32600,
|
||||
|
|
@ -1237,4 +1237,4 @@ export type ClientResult = z.infer<typeof ClientResultSchema>;
|
|||
/* Server messages */
|
||||
export type ServerRequest = z.infer<typeof ServerRequestSchema>;
|
||||
export type ServerNotification = z.infer<typeof ServerNotificationSchema>;
|
||||
export type ServerResult = z.infer<typeof ServerResultSchema>;
|
||||
export type ServerResult = z.infer<typeof ServerResultSchema>;
|
||||
Loading…
Reference in a new issue