Skip to content

Commit 7cc7e81

Browse files
committed
Support custom client request, notification, and result types
1 parent 9b4c949 commit 7cc7e81

File tree

2 files changed

+102
-4
lines changed

2 files changed

+102
-4
lines changed

src/client/index.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { Client } from "./index.js";
2+
import { z } from "zod";
3+
import { RequestSchema, NotificationSchema, ResultSchema } from "../types.js";
4+
5+
/*
6+
Test that custom request/notification/result schemas can be used with the Client class.
7+
*/
8+
const GetWeatherRequestSchema = RequestSchema.extend({
9+
method: z.literal("weather/get"),
10+
params: z.object({
11+
city: z.string(),
12+
}),
13+
});
14+
15+
const GetForecastRequestSchema = RequestSchema.extend({
16+
method: z.literal("weather/forecast"),
17+
params: z.object({
18+
city: z.string(),
19+
days: z.number(),
20+
}),
21+
});
22+
23+
const WeatherForecastNotificationSchema = NotificationSchema.extend({
24+
method: z.literal("weather/alert"),
25+
params: z.object({
26+
severity: z.enum(["warning", "watch"]),
27+
message: z.string(),
28+
}),
29+
});
30+
31+
const WeatherRequestSchema = GetWeatherRequestSchema.or(
32+
GetForecastRequestSchema,
33+
);
34+
const WeatherNotificationSchema = WeatherForecastNotificationSchema;
35+
const WeatherResultSchema = ResultSchema.extend({
36+
temperature: z.number(),
37+
conditions: z.string(),
38+
});
39+
40+
type WeatherRequest = z.infer<typeof WeatherRequestSchema>;
41+
type WeatherNotification = z.infer<typeof WeatherNotificationSchema>;
42+
type WeatherResult = z.infer<typeof WeatherResultSchema>;
43+
44+
// Create a typed Client for weather data
45+
const weatherClient = new Client<
46+
WeatherRequest,
47+
WeatherNotification,
48+
WeatherResult
49+
>({
50+
name: "WeatherClient",
51+
version: "1.0.0",
52+
});
53+
54+
// Typecheck that only valid weather requests/notifications/results are allowed
55+
weatherClient.request(
56+
{
57+
method: "weather/get",
58+
params: {
59+
city: "Seattle",
60+
},
61+
},
62+
WeatherResultSchema,
63+
);
64+
65+
weatherClient.notification({
66+
method: "weather/alert",
67+
params: {
68+
severity: "warning",
69+
message: "Storm approaching",
70+
},
71+
});

src/client/index.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,46 @@ import {
66
ClientResult,
77
Implementation,
88
InitializeResultSchema,
9+
Notification,
910
PROTOCOL_VERSION,
11+
Request,
12+
Result,
1013
ServerCapabilities,
1114
} from "../types.js";
1215

1316
/**
1417
* An MCP client on top of a pluggable transport.
1518
*
1619
* The client will automatically begin the initialization flow with the server when connect() is called.
20+
*
21+
* To use with custom types, extend the base Request/Notification/Result types and pass them as type parameters:
22+
*
23+
* ```typescript
24+
* // Custom schemas
25+
* const CustomRequestSchema = RequestSchema.extend({...})
26+
* const CustomNotificationSchema = NotificationSchema.extend({...})
27+
* const CustomResultSchema = ResultSchema.extend({...})
28+
*
29+
* // Type aliases
30+
* type CustomRequest = z.infer<typeof CustomRequestSchema>
31+
* type CustomNotification = z.infer<typeof CustomNotificationSchema>
32+
* type CustomResult = z.infer<typeof CustomResultSchema>
33+
*
34+
* // Create typed client
35+
* const client = new Client<CustomRequest, CustomNotification, CustomResult>({
36+
* name: "CustomClient",
37+
* version: "1.0.0"
38+
* })
39+
* ```
1740
*/
18-
export class Client extends Protocol<
19-
ClientRequest,
20-
ClientNotification,
21-
ClientResult
41+
export class Client<
42+
RequestT extends Request = Request,
43+
NotificationT extends Notification = Notification,
44+
ResultT extends Result = Result,
45+
> extends Protocol<
46+
ClientRequest | RequestT,
47+
ClientNotification | NotificationT,
48+
ClientResult | ResultT
2249
> {
2350
private _serverCapabilities?: ServerCapabilities;
2451
private _serverVersion?: Implementation;

0 commit comments

Comments
 (0)