Model Context Protocol in OCaml
1open Jsonrpc
2
3(* Common types *)
4
5module Role = struct
6 type t = [ `User | `Assistant ]
7
8 let to_string = function
9 | `User -> "user"
10 | `Assistant -> "assistant"
11
12 let of_string = function
13 | "user" -> `User
14 | "assistant" -> `Assistant
15 | s -> raise (Json.Of_json ("Unknown role: " ^ s, `String s))
16
17 let yojson_of_t t = `String (to_string t)
18 let t_of_yojson = function
19 | `String s -> of_string s
20 | j -> raise (Json.Of_json ("Expected string for Role", j))
21end
22
23module ProgressToken = struct
24 type t = [ `String of string | `Int of int ]
25
26 include (Id : Json.Jsonable.S with type t := t)
27end
28
29module RequestId = Id
30
31module Cursor = struct
32 type t = string
33
34 let yojson_of_t t = `String t
35 let t_of_yojson = function
36 | `String s -> s
37 | j -> raise (Json.Of_json ("Expected string for Cursor", j))
38end
39
40(* Annotations *)
41
42module Annotated = struct
43 type t = {
44 annotations: annotation option;
45 }
46 and annotation = {
47 audience: Role.t list option;
48 priority: float option;
49 }
50
51 let yojson_of_annotation { audience; priority } =
52 let assoc = [] in
53 let assoc = match audience with
54 | Some audience -> ("audience", `List (List.map Role.yojson_of_t audience)) :: assoc
55 | None -> assoc
56 in
57 let assoc = match priority with
58 | Some priority -> ("priority", `Float priority) :: assoc
59 | None -> assoc
60 in
61 `Assoc assoc
62
63 let annotation_of_yojson = function
64 | `Assoc fields ->
65 let audience = List.assoc_opt "audience" fields |> Option.map (function
66 | `List items -> List.map Role.t_of_yojson items
67 | j -> raise (Json.Of_json ("Expected list for audience", j))
68 ) in
69 let priority = List.assoc_opt "priority" fields |> Option.map (function
70 | `Float f -> f
71 | j -> raise (Json.Of_json ("Expected float for priority", j))
72 ) in
73 { audience; priority }
74 | j -> raise (Json.Of_json ("Expected object for annotation", j))
75
76 let yojson_of_t { annotations } =
77 match annotations with
78 | Some annotations -> `Assoc [ "annotations", yojson_of_annotation annotations ]
79 | None -> `Assoc []
80
81 let t_of_yojson = function
82 | `Assoc fields ->
83 let annotations = List.assoc_opt "annotations" fields |> Option.map annotation_of_yojson in
84 { annotations }
85 | j -> raise (Json.Of_json ("Expected object for Annotated", j))
86end
87
88(* Content types *)
89
90module TextContent = struct
91 type t = {
92 text: string;
93 annotations: Annotated.annotation option;
94 }
95
96 let yojson_of_t { text; annotations } =
97 let assoc = [
98 ("text", `String text);
99 ("type", `String "text");
100 ] in
101 let assoc = match annotations with
102 | Some annotations -> ("annotations", Annotated.yojson_of_annotation annotations) :: assoc
103 | None -> assoc
104 in
105 `Assoc assoc
106
107 let t_of_yojson = function
108 | `Assoc fields ->
109 let text = match List.assoc_opt "text" fields with
110 | Some (`String s) -> s
111 | _ -> raise (Json.Of_json ("Missing or invalid 'text' field", `Assoc fields))
112 in
113 let _ = match List.assoc_opt "type" fields with
114 | Some (`String "text") -> ()
115 | _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
116 in
117 let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
118 { text; annotations }
119 | j -> raise (Json.Of_json ("Expected object for TextContent", j))
120end
121
122module ImageContent = struct
123 type t = {
124 data: string;
125 mime_type: string;
126 annotations: Annotated.annotation option;
127 }
128
129 let yojson_of_t { data; mime_type; annotations } =
130 let assoc = [
131 ("data", `String data);
132 ("mimeType", `String mime_type);
133 ("type", `String "image");
134 ] in
135 let assoc = match annotations with
136 | Some annotations -> ("annotations", Annotated.yojson_of_annotation annotations) :: assoc
137 | None -> assoc
138 in
139 `Assoc assoc
140
141 let t_of_yojson = function
142 | `Assoc fields ->
143 let data = match List.assoc_opt "data" fields with
144 | Some (`String s) -> s
145 | _ -> raise (Json.Of_json ("Missing or invalid 'data' field", `Assoc fields))
146 in
147 let mime_type = match List.assoc_opt "mimeType" fields with
148 | Some (`String s) -> s
149 | _ -> raise (Json.Of_json ("Missing or invalid 'mimeType' field", `Assoc fields))
150 in
151 let _ = match List.assoc_opt "type" fields with
152 | Some (`String "image") -> ()
153 | _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
154 in
155 let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
156 { data; mime_type; annotations }
157 | j -> raise (Json.Of_json ("Expected object for ImageContent", j))
158end
159
160module ResourceContents = struct
161 type t = {
162 uri: string;
163 mime_type: string option;
164 }
165
166 let yojson_of_t { uri; mime_type } =
167 let assoc = [
168 ("uri", `String uri);
169 ] in
170 let assoc = match mime_type with
171 | Some mime_type -> ("mimeType", `String mime_type) :: assoc
172 | None -> assoc
173 in
174 `Assoc assoc
175
176 let t_of_yojson = function
177 | `Assoc fields ->
178 let uri = match List.assoc_opt "uri" fields with
179 | Some (`String s) -> s
180 | _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
181 in
182 let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
183 | `String s -> s
184 | j -> raise (Json.Of_json ("Expected string for mimeType", j))
185 ) in
186 { uri; mime_type }
187 | j -> raise (Json.Of_json ("Expected object for ResourceContents", j))
188end
189
190module TextResourceContents = struct
191 type t = {
192 uri: string;
193 text: string;
194 mime_type: string option;
195 }
196
197 let yojson_of_t { uri; text; mime_type } =
198 let assoc = [
199 ("uri", `String uri);
200 ("text", `String text);
201 ] in
202 let assoc = match mime_type with
203 | Some mime_type -> ("mimeType", `String mime_type) :: assoc
204 | None -> assoc
205 in
206 `Assoc assoc
207
208 let t_of_yojson = function
209 | `Assoc fields ->
210 let uri = match List.assoc_opt "uri" fields with
211 | Some (`String s) -> s
212 | _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
213 in
214 let text = match List.assoc_opt "text" fields with
215 | Some (`String s) -> s
216 | _ -> raise (Json.Of_json ("Missing or invalid 'text' field", `Assoc fields))
217 in
218 let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
219 | `String s -> s
220 | j -> raise (Json.Of_json ("Expected string for mimeType", j))
221 ) in
222 { uri; text; mime_type }
223 | j -> raise (Json.Of_json ("Expected object for TextResourceContents", j))
224end
225
226module BlobResourceContents = struct
227 type t = {
228 uri: string;
229 blob: string;
230 mime_type: string option;
231 }
232
233 let yojson_of_t { uri; blob; mime_type } =
234 let assoc = [
235 ("uri", `String uri);
236 ("blob", `String blob);
237 ] in
238 let assoc = match mime_type with
239 | Some mime_type -> ("mimeType", `String mime_type) :: assoc
240 | None -> assoc
241 in
242 `Assoc assoc
243
244 let t_of_yojson = function
245 | `Assoc fields ->
246 let uri = match List.assoc_opt "uri" fields with
247 | Some (`String s) -> s
248 | _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
249 in
250 let blob = match List.assoc_opt "blob" fields with
251 | Some (`String s) -> s
252 | _ -> raise (Json.Of_json ("Missing or invalid 'blob' field", `Assoc fields))
253 in
254 let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
255 | `String s -> s
256 | j -> raise (Json.Of_json ("Expected string for mimeType", j))
257 ) in
258 { uri; blob; mime_type }
259 | j -> raise (Json.Of_json ("Expected object for BlobResourceContents", j))
260end
261
262module EmbeddedResource = struct
263 type t = {
264 resource: [ `Text of TextResourceContents.t | `Blob of BlobResourceContents.t ];
265 annotations: Annotated.annotation option;
266 }
267
268 let yojson_of_t { resource; annotations } =
269 let resource_json = match resource with
270 | `Text txt -> TextResourceContents.yojson_of_t txt
271 | `Blob blob -> BlobResourceContents.yojson_of_t blob
272 in
273 let assoc = [
274 ("resource", resource_json);
275 ("type", `String "resource");
276 ] in
277 let assoc = match annotations with
278 | Some annotations -> ("annotations", Annotated.yojson_of_annotation annotations) :: assoc
279 | None -> assoc
280 in
281 `Assoc assoc
282
283 let t_of_yojson = function
284 | `Assoc fields ->
285 let _ = match List.assoc_opt "type" fields with
286 | Some (`String "resource") -> ()
287 | _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
288 in
289 let resource = match List.assoc_opt "resource" fields with
290 | Some (`Assoc res_fields) ->
291 if List.mem_assoc "text" res_fields then
292 `Text (TextResourceContents.t_of_yojson (`Assoc res_fields))
293 else if List.mem_assoc "blob" res_fields then
294 `Blob (BlobResourceContents.t_of_yojson (`Assoc res_fields))
295 else
296 raise (Json.Of_json ("Invalid resource content", `Assoc res_fields))
297 | _ -> raise (Json.Of_json ("Missing or invalid 'resource' field", `Assoc fields))
298 in
299 let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
300 { resource; annotations }
301 | j -> raise (Json.Of_json ("Expected object for EmbeddedResource", j))
302end
303
304type content =
305 | Text of TextContent.t
306 | Image of ImageContent.t
307 | Resource of EmbeddedResource.t
308
309let yojson_of_content = function
310 | Text t -> TextContent.yojson_of_t t
311 | Image i -> ImageContent.yojson_of_t i
312 | Resource r -> EmbeddedResource.yojson_of_t r
313
314let content_of_yojson = function
315 | `Assoc fields ->
316 (match List.assoc_opt "type" fields with
317 | Some (`String "text") -> Text (TextContent.t_of_yojson (`Assoc fields))
318 | Some (`String "image") -> Image (ImageContent.t_of_yojson (`Assoc fields))
319 | Some (`String "resource") -> Resource (EmbeddedResource.t_of_yojson (`Assoc fields))
320 | _ -> raise (Json.Of_json ("Invalid or missing content type", `Assoc fields)))
321 | j -> raise (Json.Of_json ("Expected object for content", j))
322
323(* Message types *)
324
325module PromptMessage = struct
326 type t = {
327 role: Role.t;
328 content: content;
329 }
330
331 let yojson_of_t { role; content } =
332 `Assoc [
333 ("role", Role.yojson_of_t role);
334 ("content", yojson_of_content content);
335 ]
336
337 let t_of_yojson = function
338 | `Assoc fields ->
339 let role = match List.assoc_opt "role" fields with
340 | Some json -> Role.t_of_yojson json
341 | None -> raise (Json.Of_json ("Missing role field", `Assoc fields))
342 in
343 let content = match List.assoc_opt "content" fields with
344 | Some json -> content_of_yojson json
345 | None -> raise (Json.Of_json ("Missing content field", `Assoc fields))
346 in
347 { role; content }
348 | j -> raise (Json.Of_json ("Expected object for PromptMessage", j))
349end
350
351module SamplingMessage = struct
352 type t = {
353 role: Role.t;
354 content: [ `Text of TextContent.t | `Image of ImageContent.t ];
355 }
356
357 let yojson_of_t { role; content } =
358 let content_json = match content with
359 | `Text t -> TextContent.yojson_of_t t
360 | `Image i -> ImageContent.yojson_of_t i
361 in
362 `Assoc [
363 ("role", Role.yojson_of_t role);
364 ("content", content_json);
365 ]
366
367 let t_of_yojson = function
368 | `Assoc fields ->
369 let role = match List.assoc_opt "role" fields with
370 | Some json -> Role.t_of_yojson json
371 | None -> raise (Json.Of_json ("Missing role field", `Assoc fields))
372 in
373 let content = match List.assoc_opt "content" fields with
374 | Some (`Assoc content_fields) ->
375 (match List.assoc_opt "type" content_fields with
376 | Some (`String "text") -> `Text (TextContent.t_of_yojson (`Assoc content_fields))
377 | Some (`String "image") -> `Image (ImageContent.t_of_yojson (`Assoc content_fields))
378 | _ -> raise (Json.Of_json ("Invalid content type", `Assoc content_fields)))
379 | _ -> raise (Json.Of_json ("Missing or invalid content field", `Assoc fields))
380 in
381 { role; content }
382 | j -> raise (Json.Of_json ("Expected object for SamplingMessage", j))
383end
384
385(* Implementation info *)
386
387module Implementation = struct
388 type t = {
389 name: string;
390 version: string;
391 }
392
393 let yojson_of_t { name; version } =
394 `Assoc [
395 ("name", `String name);
396 ("version", `String version);
397 ]
398
399 let t_of_yojson = function
400 | `Assoc fields ->
401 let name = match List.assoc_opt "name" fields with
402 | Some (`String s) -> s
403 | _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields))
404 in
405 let version = match List.assoc_opt "version" fields with
406 | Some (`String s) -> s
407 | _ -> raise (Json.Of_json ("Missing or invalid 'version' field", `Assoc fields))
408 in
409 { name; version }
410 | j -> raise (Json.Of_json ("Expected object for Implementation", j))
411end
412
413(* JSONRPC Message types *)
414
415module JSONRPCMessage = struct
416 type notification = {
417 method_: string;
418 params: Json.t option;
419 }
420
421 type request = {
422 id: RequestId.t;
423 method_: string;
424 params: Json.t option;
425 progress_token: ProgressToken.t option;
426 }
427
428 type response = {
429 id: RequestId.t;
430 result: Json.t;
431 }
432
433 type error = {
434 id: RequestId.t;
435 code: int;
436 message: string;
437 data: Json.t option;
438 }
439
440 type t =
441 | Notification of notification
442 | Request of request
443 | Response of response
444 | Error of error
445
446 let yojson_of_notification (n: notification) =
447 let assoc = [
448 ("jsonrpc", `String "2.0");
449 ("method", `String n.method_);
450 ] in
451 let assoc = match n.params with
452 | Some params -> ("params", params) :: assoc
453 | None -> assoc
454 in
455 `Assoc assoc
456
457 let yojson_of_request (r: request) =
458 let assoc = [
459 ("jsonrpc", `String "2.0");
460 ("id", Id.yojson_of_t r.id);
461 ("method", `String r.method_);
462 ] in
463 let assoc = match r.params with
464 | Some params ->
465 let params_json = match params with
466 | `Assoc fields ->
467 let fields = match r.progress_token with
468 | Some token ->
469 let meta = `Assoc [ "progressToken", ProgressToken.yojson_of_t token ] in
470 ("_meta", meta) :: fields
471 | None -> fields
472 in
473 `Assoc fields
474 | _ -> params
475 in
476 ("params", params_json) :: assoc
477 | None -> assoc
478 in
479 `Assoc assoc
480
481 let yojson_of_response (r: response) =
482 `Assoc [
483 ("jsonrpc", `String "2.0");
484 ("id", Id.yojson_of_t r.id);
485 ("result", r.result);
486 ]
487
488 let yojson_of_error (e: error) =
489 let error_assoc = [
490 ("code", `Int e.code);
491 ("message", `String e.message);
492 ] in
493 let error_assoc = match e.data with
494 | Some data -> ("data", data) :: error_assoc
495 | None -> error_assoc
496 in
497 `Assoc [
498 ("jsonrpc", `String "2.0");
499 ("id", Id.yojson_of_t e.id);
500 ("error", `Assoc error_assoc);
501 ]
502
503 let yojson_of_t = function
504 | Notification n -> yojson_of_notification n
505 | Request r -> yojson_of_request r
506 | Response r -> yojson_of_response r
507 | Error e -> yojson_of_error e
508
509 let notification_of_yojson = function
510 | `Assoc fields ->
511 let method_ = match List.assoc_opt "method" fields with
512 | Some (`String s) -> s
513 | _ -> raise (Json.Of_json ("Missing or invalid 'method' field", `Assoc fields))
514 in
515 let params = List.assoc_opt "params" fields in
516 { method_; params }
517 | j -> raise (Json.Of_json ("Expected object for notification", j))
518
519 let request_of_yojson = function
520 | `Assoc fields ->
521 let id = match List.assoc_opt "id" fields with
522 | Some id_json -> Id.t_of_yojson id_json
523 | _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields))
524 in
525 let method_ = match List.assoc_opt "method" fields with
526 | Some (`String s) -> s
527 | _ -> raise (Json.Of_json ("Missing or invalid 'method' field", `Assoc fields))
528 in
529 let params = List.assoc_opt "params" fields in
530 let progress_token =
531 match params with
532 | Some (`Assoc param_fields) ->
533 (match List.assoc_opt "_meta" param_fields with
534 | Some (`Assoc meta_fields) ->
535 (match List.assoc_opt "progressToken" meta_fields with
536 | Some token_json -> Some (ProgressToken.t_of_yojson token_json)
537 | None -> None)
538 | _ -> None)
539 | _ -> None
540 in
541 { id; method_; params; progress_token }
542 | j -> raise (Json.Of_json ("Expected object for request", j))
543
544 let response_of_yojson = function
545 | `Assoc fields ->
546 let id = match List.assoc_opt "id" fields with
547 | Some id_json -> Id.t_of_yojson id_json
548 | _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields))
549 in
550 let result = match List.assoc_opt "result" fields with
551 | Some result -> result
552 | _ -> raise (Json.Of_json ("Missing 'result' field", `Assoc fields))
553 in
554 { id; result }
555 | j -> raise (Json.Of_json ("Expected object for response", j))
556
557 let error_of_yojson = function
558 | `Assoc fields ->
559 let id = match List.assoc_opt "id" fields with
560 | Some id_json -> Id.t_of_yojson id_json
561 | _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields))
562 in
563 let error = match List.assoc_opt "error" fields with
564 | Some (`Assoc error_fields) -> error_fields
565 | _ -> raise (Json.Of_json ("Missing or invalid 'error' field", `Assoc fields))
566 in
567 let code = match List.assoc_opt "code" error with
568 | Some (`Int code) -> code
569 | _ -> raise (Json.Of_json ("Missing or invalid 'code' field in error", `Assoc error))
570 in
571 let message = match List.assoc_opt "message" error with
572 | Some (`String msg) -> msg
573 | _ -> raise (Json.Of_json ("Missing or invalid 'message' field in error", `Assoc error))
574 in
575 let data = List.assoc_opt "data" error in
576 { id; code; message; data }
577 | j -> raise (Json.Of_json ("Expected object for error", j))
578
579 let t_of_yojson json =
580 match json with
581 | `Assoc fields ->
582 let _jsonrpc = match List.assoc_opt "jsonrpc" fields with
583 | Some (`String "2.0") -> ()
584 | _ -> raise (Json.Of_json ("Missing or invalid 'jsonrpc' field", json))
585 in
586 if List.mem_assoc "method" fields then
587 if List.mem_assoc "id" fields then
588 Request (request_of_yojson json)
589 else
590 Notification (notification_of_yojson json)
591 else if List.mem_assoc "result" fields then
592 Response (response_of_yojson json)
593 else if List.mem_assoc "error" fields then
594 Error (error_of_yojson json)
595 else
596 raise (Json.Of_json ("Invalid JSONRPC message format", json))
597 | j -> raise (Json.Of_json ("Expected object for JSONRPC message", j))
598
599 let create_notification ?(params=None) ~method_ () =
600 Notification { method_; params }
601
602 let create_request ?(params=None) ?(progress_token=None) ~id ~method_ () =
603 Request { id; method_; params; progress_token }
604
605 let create_response ~id ~result =
606 Response { id; result }
607
608 let create_error ~id ~code ~message ?(data=None) () =
609 Error { id; code; message; data }
610end
611
612(* MCP-specific request/response types *)
613
614module Initialize = struct
615 module Request = struct
616 type t = {
617 capabilities: Json.t; (* ClientCapabilities *)
618 client_info: Implementation.t;
619 protocol_version: string;
620 }
621
622 let yojson_of_t { capabilities; client_info; protocol_version } =
623 `Assoc [
624 ("capabilities", capabilities);
625 ("clientInfo", Implementation.yojson_of_t client_info);
626 ("protocolVersion", `String protocol_version);
627 ]
628
629 let t_of_yojson = function
630 | `Assoc fields ->
631 let capabilities = match List.assoc_opt "capabilities" fields with
632 | Some json -> json
633 | None -> raise (Json.Of_json ("Missing capabilities field", `Assoc fields))
634 in
635 let client_info = match List.assoc_opt "clientInfo" fields with
636 | Some json -> Implementation.t_of_yojson json
637 | None -> raise (Json.Of_json ("Missing clientInfo field", `Assoc fields))
638 in
639 let protocol_version = match List.assoc_opt "protocolVersion" fields with
640 | Some (`String s) -> s
641 | _ -> raise (Json.Of_json ("Missing or invalid protocolVersion field", `Assoc fields))
642 in
643 { capabilities; client_info; protocol_version }
644 | j -> raise (Json.Of_json ("Expected object for InitializeRequest", j))
645
646 let create ~capabilities ~client_info ~protocol_version =
647 { capabilities; client_info; protocol_version }
648
649 let to_jsonrpc ~id t =
650 let params = yojson_of_t t in
651 JSONRPCMessage.create_request ~id ~method_:"initialize" ~params:(Some params) ()
652 end
653
654 module Result = struct
655 type t = {
656 capabilities: Json.t; (* ServerCapabilities *)
657 server_info: Implementation.t;
658 protocol_version: string;
659 instructions: string option;
660 meta: Json.t option;
661 }
662
663 let yojson_of_t { capabilities; server_info; protocol_version; instructions; meta } =
664 let assoc = [
665 ("capabilities", capabilities);
666 ("serverInfo", Implementation.yojson_of_t server_info);
667 ("protocolVersion", `String protocol_version);
668 ] in
669 let assoc = match instructions with
670 | Some instr -> ("instructions", `String instr) :: assoc
671 | None -> assoc
672 in
673 let assoc = match meta with
674 | Some meta -> ("_meta", meta) :: assoc
675 | None -> assoc
676 in
677 `Assoc assoc
678
679 let t_of_yojson = function
680 | `Assoc fields ->
681 let capabilities = match List.assoc_opt "capabilities" fields with
682 | Some json -> json
683 | None -> raise (Json.Of_json ("Missing capabilities field", `Assoc fields))
684 in
685 let server_info = match List.assoc_opt "serverInfo" fields with
686 | Some json -> Implementation.t_of_yojson json
687 | None -> raise (Json.Of_json ("Missing serverInfo field", `Assoc fields))
688 in
689 let protocol_version = match List.assoc_opt "protocolVersion" fields with
690 | Some (`String s) -> s
691 | _ -> raise (Json.Of_json ("Missing or invalid protocolVersion field", `Assoc fields))
692 in
693 let instructions = match List.assoc_opt "instructions" fields with
694 | Some (`String s) -> Some s
695 | _ -> None
696 in
697 let meta = List.assoc_opt "_meta" fields in
698 { capabilities; server_info; protocol_version; instructions; meta }
699 | j -> raise (Json.Of_json ("Expected object for InitializeResult", j))
700
701 let create ~capabilities ~server_info ~protocol_version ?instructions ?meta () =
702 { capabilities; server_info; protocol_version; instructions; meta }
703
704 let to_jsonrpc ~id t =
705 JSONRPCMessage.create_response ~id ~result:(yojson_of_t t)
706 end
707end
708
709module Initialized = struct
710 module Notification = struct
711 type t = {
712 meta: Json.t option;
713 }
714
715 let yojson_of_t { meta } =
716 let assoc = [] in
717 let assoc = match meta with
718 | Some meta -> ("_meta", meta) :: assoc
719 | None -> assoc
720 in
721 `Assoc assoc
722
723 let t_of_yojson = function
724 | `Assoc fields ->
725 let meta = List.assoc_opt "_meta" fields in
726 { meta }
727 | j -> raise (Json.Of_json ("Expected object for InitializedNotification", j))
728
729 let create ?meta () = { meta }
730
731 let to_jsonrpc t =
732 let params = match yojson_of_t t with
733 | `Assoc [] -> None
734 | json -> Some json
735 in
736 JSONRPCMessage.create_notification ~method_:"notifications/initialized" ~params ()
737 end
738end
739
740(* Export the main interface for using the MCP protocol *)
741
742let parse_message json =
743 JSONRPCMessage.t_of_yojson json
744
745let create_notification = JSONRPCMessage.create_notification
746let create_request = JSONRPCMessage.create_request
747let create_response = JSONRPCMessage.create_response
748let create_error = JSONRPCMessage.create_error