···
3
-
(* Utility functions for JSON parsing *)
5
-
(* Helper to raise a Json.Of_json exception with formatted message *)
6
-
let json_error fmt json =
7
-
Printf.ksprintf (fun msg -> raise (Json.Of_json (msg, json))) fmt
9
-
(* Extract a string field from JSON object or raise an error *)
10
-
let get_string_field fields name json =
11
-
match List.assoc_opt name fields with
12
-
| Some (`String s) -> s
13
-
| _ -> json_error "Missing or invalid '%s' field" json name
15
-
(* Extract an optional string field from JSON object *)
16
-
let get_optional_string_field fields name =
17
-
List.assoc_opt name fields
18
-
|> Option.map (function
20
-
| j -> json_error "Expected string for %s" j name)
22
-
(* Extract an int field from JSON object or raise an error *)
23
-
let get_int_field fields name json =
24
-
match List.assoc_opt name fields with
25
-
| Some (`Int i) -> i
26
-
| _ -> json_error "Missing or invalid '%s' field" json name
28
-
(* Extract a float field from JSON object or raise an error *)
29
-
let get_float_field fields name json =
30
-
match List.assoc_opt name fields with
31
-
| Some (`Float f) -> f
32
-
| _ -> json_error "Missing or invalid '%s' field" json name
34
-
(* Extract a boolean field from JSON object or raise an error *)
35
-
let get_bool_field fields name json =
36
-
match List.assoc_opt name fields with
37
-
| Some (`Bool b) -> b
38
-
| _ -> json_error "Missing or invalid '%s' field" json name
40
-
(* Extract an object field from JSON object or raise an error *)
41
-
let get_object_field fields name json =
42
-
match List.assoc_opt name fields with
43
-
| Some (`Assoc obj) -> obj
44
-
| _ -> json_error "Missing or invalid '%s' field" json name
46
-
(* Extract a list field from JSON object or raise an error *)
47
-
let get_list_field fields name json =
48
-
match List.assoc_opt name fields with
49
-
| Some (`List items) -> items
50
-
| _ -> json_error "Missing or invalid '%s' field" json name
52
-
(* Verify a specific string value in a field *)
53
-
let verify_string_field fields name expected_value json =
54
-
match List.assoc_opt name fields with
55
-
| Some (`String s) when s = expected_value -> ()
57
-
json_error "Field '%s' missing or not equal to '%s'" json name
61
-
(* Error codes for JSON-RPC *)
3
+
(* Standard error codes *)
module ErrorCode = struct
64
-
| ParseError (* -32700 - Invalid JSON *)
65
-
| InvalidRequest (* -32600 - Invalid JSON-RPC request *)
66
-
| MethodNotFound (* -32601 - Method not available *)
67
-
| InvalidParams (* -32602 - Invalid method parameters *)
68
-
| InternalError (* -32603 - Internal JSON-RPC error *)
70
-
(* -32002 - Custom MCP error: requested resource not found *)
71
-
| AuthRequired (* -32001 - Custom MCP error: authentication required *)
72
-
| CustomError of int (* For any other error codes *)
74
-
(* Convert the error code to its integer representation *)
75
-
let to_int = function
76
-
| ParseError -> -32700
77
-
| InvalidRequest -> -32600
78
-
| MethodNotFound -> -32601
79
-
| InvalidParams -> -32602
80
-
| InternalError -> -32603
81
-
| ResourceNotFound -> -32002
82
-
| AuthRequired -> -32001
83
-
| CustomError code -> code
85
-
(* Get error message for standard error codes *)
86
-
let to_message = function
87
-
| ParseError -> "Parse error"
88
-
| InvalidRequest -> "Invalid Request"
89
-
| MethodNotFound -> "Method not found"
90
-
| InvalidParams -> "Invalid params"
91
-
| InternalError -> "Internal error"
92
-
| ResourceNotFound -> "Resource not found"
93
-
| AuthRequired -> "Authentication required"
94
-
| CustomError _ -> "Error"
97
-
(* Protocol method types *)
98
-
module Method = struct
99
-
(* Method type representing all MCP protocol methods *)
101
-
(* Initialization and lifecycle methods *)
104
-
(* Resource methods *)
107
-
| ResourceTemplatesList
108
-
| ResourcesSubscribe
109
-
| ResourcesListChanged
115
-
(* Prompt methods *)
118
-
| PromptsListChanged
119
-
(* Progress notifications *)
122
-
(* Convert method type to string representation *)
123
-
let to_string = function
124
-
| Initialize -> "initialize"
125
-
| Initialized -> "notifications/initialized"
126
-
| ResourcesList -> "resources/list"
127
-
| ResourcesRead -> "resources/read"
128
-
| ResourceTemplatesList -> "resources/templates/list"
129
-
| ResourcesSubscribe -> "resources/subscribe"
130
-
| ResourcesListChanged -> "notifications/resources/list_changed"
131
-
| ResourcesUpdated -> "notifications/resources/updated"
132
-
| ToolsList -> "tools/list"
133
-
| ToolsCall -> "tools/call"
134
-
| ToolsListChanged -> "notifications/tools/list_changed"
135
-
| PromptsList -> "prompts/list"
136
-
| PromptsGet -> "prompts/get"
137
-
| PromptsListChanged -> "notifications/prompts/list_changed"
138
-
| Progress -> "notifications/progress"
140
-
(* Convert string to method type *)
141
-
let of_string = function
142
-
| "initialize" -> Initialize
143
-
| "notifications/initialized" -> Initialized
144
-
| "resources/list" -> ResourcesList
145
-
| "resources/read" -> ResourcesRead
146
-
| "resources/templates/list" -> ResourceTemplatesList
147
-
| "resources/subscribe" -> ResourcesSubscribe
148
-
| "notifications/resources/list_changed" -> ResourcesListChanged
149
-
| "notifications/resources/updated" -> ResourcesUpdated
150
-
| "tools/list" -> ToolsList
151
-
| "tools/call" -> ToolsCall
152
-
| "notifications/tools/list_changed" -> ToolsListChanged
153
-
| "prompts/list" -> PromptsList
154
-
| "prompts/get" -> PromptsGet
155
-
| "notifications/prompts/list_changed" -> PromptsListChanged
156
-
| "notifications/progress" -> Progress
157
-
| s -> failwith ("Unknown MCP method: " ^ s)
5
+
let parse_error = -32700
6
+
let invalid_request = -32600
7
+
let method_not_found = -32601
8
+
let invalid_params = -32602
9
+
let internal_error = -32603
10
+
let resource_not_found = -32002
11
+
let server_error_start = -32000
12
+
let server_error_end = -32099
···
type t = [ `User | `Assistant ]
165
-
let to_string = function `User -> "user" | `Assistant -> "assistant"
20
+
let to_string = function
22
+
| `Assistant -> "assistant"
| "assistant" -> `Assistant
170
-
| s -> Util.json_error "Unknown role: %s" (`String s) s
27
+
| s -> raise (Json.Of_json ("Unknown role: " ^ s, `String s))
let yojson_of_t t = `String (to_string t)
let t_of_yojson = function
| `String s -> of_string s
176
-
| j -> Util.json_error "Expected string for Role" j
32
+
| j -> raise (Json.Of_json ("Expected string for Role", j))
module ProgressToken = struct
···
let yojson_of_t t = `String t
let t_of_yojson = function
194
-
| j -> Util.json_error "Expected string for Cursor" j
49
+
| j -> raise (Json.Of_json ("Expected string for Cursor", j))
module Annotated = struct
200
-
type t = { annotations : annotation option }
201
-
and annotation = { audience : Role.t list option; priority : float option }
56
+
annotations: annotation option;
59
+
audience: Role.t list option;
60
+
priority: float option;
let yojson_of_annotation { audience; priority } =
206
-
match audience with
208
-
("audience", `List (List.map Role.yojson_of_t audience)) :: assoc
65
+
let assoc = match audience with
66
+
| Some audience -> ("audience", `List (List.map Role.yojson_of_t audience)) :: assoc
212
-
match priority with
69
+
let assoc = match priority with
| Some priority -> ("priority", `Float priority) :: assoc
···
let annotation_of_yojson = function
221
-
List.assoc_opt "audience" fields
222
-
|> Option.map (function
223
-
| `List items -> List.map Role.t_of_yojson items
224
-
| j -> Util.json_error "Expected list for audience" j)
227
-
List.assoc_opt "priority" fields
228
-
|> Option.map (function
230
-
| j -> Util.json_error "Expected float for priority" j)
232
-
{ audience; priority }
233
-
| j -> Util.json_error "Expected object for annotation" j
77
+
let audience = List.assoc_opt "audience" fields |> Option.map (function
78
+
| `List items -> List.map Role.t_of_yojson items
79
+
| j -> raise (Json.Of_json ("Expected list for audience", j))
81
+
let priority = List.assoc_opt "priority" fields |> Option.map (function
83
+
| j -> raise (Json.Of_json ("Expected float for priority", j))
85
+
{ audience; priority }
86
+
| j -> raise (Json.Of_json ("Expected object for annotation", j))
let yojson_of_t { annotations } =
237
-
| Some annotations ->
238
-
`Assoc [ ("annotations", yojson_of_annotation annotations) ]
90
+
| Some annotations -> `Assoc [ "annotations", yojson_of_annotation annotations ]
let t_of_yojson = function
244
-
List.assoc_opt "annotations" fields |> Option.map annotation_of_yojson
247
-
| j -> Util.json_error "Expected object for Annotated" j
95
+
let annotations = List.assoc_opt "annotations" fields |> Option.map annotation_of_yojson in
97
+
| j -> raise (Json.Of_json ("Expected object for Annotated", j))
module TextContent = struct
253
-
type t = { text : string; annotations : Annotated.annotation option }
105
+
annotations: Annotated.annotation option;
let yojson_of_t { text; annotations } =
256
-
let assoc = [ ("text", `String text); ("type", `String "text") ] in
258
-
match annotations with
259
-
| Some annotations ->
260
-
("annotations", Annotated.yojson_of_annotation annotations) :: assoc
110
+
("text", `String text);
111
+
("type", `String "text");
113
+
let assoc = match annotations with
114
+
| Some annotations -> ("annotations", Annotated.yojson_of_annotation annotations) :: assoc
let t_of_yojson = function
266
-
| `Assoc fields as json ->
267
-
let text = Util.get_string_field fields "text" json in
268
-
Util.verify_string_field fields "type" "text" json;
270
-
List.assoc_opt "annotations" fields
271
-
|> Option.map Annotated.annotation_of_yojson
273
-
{ text; annotations }
274
-
| j -> Util.json_error "Expected object for TextContent" j
121
+
let text = match List.assoc_opt "text" fields with
122
+
| Some (`String s) -> s
123
+
| _ -> raise (Json.Of_json ("Missing or invalid 'text' field", `Assoc fields))
125
+
let _ = match List.assoc_opt "type" fields with
126
+
| Some (`String "text") -> ()
127
+
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
129
+
let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
130
+
{ text; annotations }
131
+
| j -> raise (Json.Of_json ("Expected object for TextContent", j))
module ImageContent = struct
280
-
mime_type : string;
281
-
annotations : Annotated.annotation option;
138
+
annotations: Annotated.annotation option;
let yojson_of_t { data; mime_type; annotations } =
287
-
("type", `String "image");
288
-
("data", `String data);
289
-
("mimeType", `String mime_type);
293
-
match annotations with
294
-
| Some annotations ->
295
-
("annotations", Annotated.yojson_of_annotation annotations) :: assoc
143
+
("data", `String data);
144
+
("mimeType", `String mime_type);
145
+
("type", `String "image");
147
+
let assoc = match annotations with
148
+
| Some annotations -> ("annotations", Annotated.yojson_of_annotation annotations) :: assoc
let t_of_yojson = function
301
-
| `Assoc fields as json ->
302
-
let data = Util.get_string_field fields "data" json in
303
-
let mime_type = Util.get_string_field fields "mimeType" json in
304
-
Util.verify_string_field fields "type" "image" json;
306
-
List.assoc_opt "annotations" fields
307
-
|> Option.map Annotated.annotation_of_yojson
309
-
{ data; mime_type; annotations }
310
-
| j -> Util.json_error "Expected object for ImageContent" j
155
+
let data = match List.assoc_opt "data" fields with
156
+
| Some (`String s) -> s
157
+
| _ -> raise (Json.Of_json ("Missing or invalid 'data' field", `Assoc fields))
159
+
let mime_type = match List.assoc_opt "mimeType" fields with
160
+
| Some (`String s) -> s
161
+
| _ -> raise (Json.Of_json ("Missing or invalid 'mimeType' field", `Assoc fields))
163
+
let _ = match List.assoc_opt "type" fields with
164
+
| Some (`String "image") -> ()
165
+
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
167
+
let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
168
+
{ data; mime_type; annotations }
169
+
| j -> raise (Json.Of_json ("Expected object for ImageContent", j))
module AudioContent = struct
316
-
mime_type : string;
317
-
annotations : Annotated.annotation option;
176
+
annotations: Annotated.annotation option;
let yojson_of_t { data; mime_type; annotations } =
323
-
("type", `String "audio");
324
-
("data", `String data);
325
-
("mimeType", `String mime_type);
329
-
match annotations with
330
-
| Some annotations ->
331
-
("annotations", Annotated.yojson_of_annotation annotations) :: assoc
181
+
("data", `String data);
182
+
("mimeType", `String mime_type);
183
+
("type", `String "audio");
185
+
let assoc = match annotations with
186
+
| Some annotations -> ("annotations", Annotated.yojson_of_annotation annotations) :: assoc
let t_of_yojson = function
337
-
| `Assoc fields as json ->
338
-
let data = Util.get_string_field fields "data" json in
339
-
let mime_type = Util.get_string_field fields "mimeType" json in
340
-
Util.verify_string_field fields "type" "audio" json;
342
-
List.assoc_opt "annotations" fields
343
-
|> Option.map Annotated.annotation_of_yojson
345
-
{ data; mime_type; annotations }
346
-
| j -> Util.json_error "Expected object for AudioContent" j
193
+
let data = match List.assoc_opt "data" fields with
194
+
| Some (`String s) -> s
195
+
| _ -> raise (Json.Of_json ("Missing or invalid 'data' field", `Assoc fields))
197
+
let mime_type = match List.assoc_opt "mimeType" fields with
198
+
| Some (`String s) -> s
199
+
| _ -> raise (Json.Of_json ("Missing or invalid 'mimeType' field", `Assoc fields))
201
+
let _ = match List.assoc_opt "type" fields with
202
+
| Some (`String "audio") -> ()
203
+
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
205
+
let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
206
+
{ data; mime_type; annotations }
207
+
| j -> raise (Json.Of_json ("Expected object for AudioContent", j))
module ResourceContents = struct
350
-
type t = { uri : string; mime_type : string option }
213
+
mime_type: string option;
let yojson_of_t { uri; mime_type } =
353
-
let assoc = [ ("uri", `String uri) ] in
355
-
match mime_type with
218
+
("uri", `String uri);
220
+
let assoc = match mime_type with
| Some mime_type -> ("mimeType", `String mime_type) :: assoc
let t_of_yojson = function
362
-
| `Assoc fields as json ->
363
-
let uri = Util.get_string_field fields "uri" json in
364
-
let mime_type = Util.get_optional_string_field fields "mimeType" in
366
-
| j -> Util.json_error "Expected object for ResourceContents" j
228
+
let uri = match List.assoc_opt "uri" fields with
229
+
| Some (`String s) -> s
230
+
| _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
232
+
let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
234
+
| j -> raise (Json.Of_json ("Expected string for mimeType", j))
237
+
| j -> raise (Json.Of_json ("Expected object for ResourceContents", j))
module TextResourceContents = struct
370
-
type t = { uri : string; text : string; mime_type : string option }
244
+
mime_type: string option;
let yojson_of_t { uri; text; mime_type } =
373
-
let assoc = [ ("uri", `String uri); ("text", `String text) ] in
375
-
match mime_type with
249
+
("uri", `String uri);
250
+
("text", `String text);
252
+
let assoc = match mime_type with
| Some mime_type -> ("mimeType", `String mime_type) :: assoc
let t_of_yojson = function
382
-
| `Assoc fields as json ->
383
-
let uri = Util.get_string_field fields "uri" json in
384
-
let text = Util.get_string_field fields "text" json in
385
-
let mime_type = Util.get_optional_string_field fields "mimeType" in
386
-
{ uri; text; mime_type }
387
-
| j -> Util.json_error "Expected object for TextResourceContents" j
260
+
let uri = match List.assoc_opt "uri" fields with
261
+
| Some (`String s) -> s
262
+
| _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
264
+
let text = match List.assoc_opt "text" fields with
265
+
| Some (`String s) -> s
266
+
| _ -> raise (Json.Of_json ("Missing or invalid 'text' field", `Assoc fields))
268
+
let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
270
+
| j -> raise (Json.Of_json ("Expected string for mimeType", j))
272
+
{ uri; text; mime_type }
273
+
| j -> raise (Json.Of_json ("Expected object for TextResourceContents", j))
module BlobResourceContents = struct
391
-
type t = { uri : string; blob : string; mime_type : string option }
280
+
mime_type: string option;
let yojson_of_t { uri; blob; mime_type } =
394
-
let assoc = [ ("uri", `String uri); ("blob", `String blob) ] in
396
-
match mime_type with
285
+
("uri", `String uri);
286
+
("blob", `String blob);
288
+
let assoc = match mime_type with
| Some mime_type -> ("mimeType", `String mime_type) :: assoc
let t_of_yojson = function
403
-
| `Assoc fields as json ->
404
-
let uri = Util.get_string_field fields "uri" json in
405
-
let blob = Util.get_string_field fields "blob" json in
406
-
let mime_type = Util.get_optional_string_field fields "mimeType" in
407
-
{ uri; blob; mime_type }
408
-
| j -> Util.json_error "Expected object for BlobResourceContents" j
296
+
let uri = match List.assoc_opt "uri" fields with
297
+
| Some (`String s) -> s
298
+
| _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
300
+
let blob = match List.assoc_opt "blob" fields with
301
+
| Some (`String s) -> s
302
+
| _ -> raise (Json.Of_json ("Missing or invalid 'blob' field", `Assoc fields))
304
+
let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function
306
+
| j -> raise (Json.Of_json ("Expected string for mimeType", j))
308
+
{ uri; blob; mime_type }
309
+
| j -> raise (Json.Of_json ("Expected object for BlobResourceContents", j))
module EmbeddedResource = struct
414
-
[ `Text of TextResourceContents.t | `Blob of BlobResourceContents.t ];
415
-
annotations : Annotated.annotation option;
314
+
resource: [ `Text of TextResourceContents.t | `Blob of BlobResourceContents.t ];
315
+
annotations: Annotated.annotation option;
let yojson_of_t { resource; annotations } =
419
-
let resource_json =
420
-
match resource with
319
+
let resource_json = match resource with
| `Text txt -> TextResourceContents.yojson_of_t txt
| `Blob blob -> BlobResourceContents.yojson_of_t blob
424
-
let assoc = [ ("resource", resource_json); ("type", `String "resource") ] in
426
-
match annotations with
427
-
| Some annotations ->
428
-
("annotations", Annotated.yojson_of_annotation annotations) :: assoc
324
+
("resource", resource_json);
325
+
("type", `String "resource");
327
+
let assoc = match annotations with
328
+
| Some annotations -> ("annotations", Annotated.yojson_of_annotation annotations) :: assoc
let t_of_yojson = function
434
-
| `Assoc fields as json ->
435
-
Util.verify_string_field fields "type" "resource" json;
436
-
let resource_fields =
437
-
match List.assoc_opt "resource" fields with
438
-
| Some (`Assoc res_fields) -> res_fields
439
-
| _ -> Util.json_error "Missing or invalid 'resource' field" json
442
-
if List.mem_assoc "text" resource_fields then
443
-
`Text (TextResourceContents.t_of_yojson (`Assoc resource_fields))
444
-
else if List.mem_assoc "blob" resource_fields then
445
-
`Blob (BlobResourceContents.t_of_yojson (`Assoc resource_fields))
335
+
let _ = match List.assoc_opt "type" fields with
336
+
| Some (`String "resource") -> ()
337
+
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
339
+
let resource = match List.assoc_opt "resource" fields with
340
+
| Some (`Assoc res_fields) ->
341
+
if List.mem_assoc "text" res_fields then
342
+
`Text (TextResourceContents.t_of_yojson (`Assoc res_fields))
343
+
else if List.mem_assoc "blob" res_fields then
344
+
`Blob (BlobResourceContents.t_of_yojson (`Assoc res_fields))
447
-
Util.json_error "Invalid resource content" (`Assoc resource_fields)
450
-
List.assoc_opt "annotations" fields
451
-
|> Option.map Annotated.annotation_of_yojson
453
-
{ resource; annotations }
454
-
| j -> Util.json_error "Expected object for EmbeddedResource" j
346
+
raise (Json.Of_json ("Invalid resource content", `Assoc res_fields))
347
+
| _ -> raise (Json.Of_json ("Missing or invalid 'resource' field", `Assoc fields))
349
+
let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in
350
+
{ resource; annotations }
351
+
| j -> raise (Json.Of_json ("Expected object for EmbeddedResource", j))
354
+
(** Tool definition *)
355
+
module Tool = struct
358
+
description: string option;
359
+
input_schema: Json.t;
362
+
let yojson_of_t { name; description; input_schema } =
364
+
("name", `String name);
365
+
("inputSchema", input_schema);
367
+
let assoc = match description with
368
+
| Some desc -> ("description", `String desc) :: assoc
373
+
let t_of_yojson = function
375
+
let name = match List.assoc_opt "name" fields with
376
+
| Some (`String s) -> s
377
+
| _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields))
379
+
let description = match List.assoc_opt "description" fields with
380
+
| Some (`String s) -> Some s
383
+
let input_schema = match List.assoc_opt "inputSchema" fields with
384
+
| Some json -> json
385
+
| _ -> raise (Json.Of_json ("Missing 'inputSchema' field", `Assoc fields))
387
+
{ name; description; input_schema }
388
+
| j -> raise (Json.Of_json ("Expected object for Tool", j))
| Image of ImageContent.t
| Audio of AudioContent.t
···
| Resource r -> EmbeddedResource.yojson_of_t r
let content_of_yojson = function
470
-
| `Assoc fields as json -> (
471
-
match List.assoc_opt "type" fields with
472
-
| Some (`String "text") -> Text (TextContent.t_of_yojson json)
473
-
| Some (`String "image") -> Image (ImageContent.t_of_yojson json)
474
-
| Some (`String "audio") -> Audio (AudioContent.t_of_yojson json)
475
-
| Some (`String "resource") ->
476
-
Resource (EmbeddedResource.t_of_yojson json)
477
-
| _ -> Util.json_error "Invalid or missing content type" json)
478
-
| j -> Util.json_error "Expected object for content" j
405
+
(match List.assoc_opt "type" fields with
406
+
| Some (`String "text") -> Text (TextContent.t_of_yojson (`Assoc fields))
407
+
| Some (`String "image") -> Image (ImageContent.t_of_yojson (`Assoc fields))
408
+
| Some (`String "audio") -> Audio (AudioContent.t_of_yojson (`Assoc fields))
409
+
| Some (`String "resource") -> Resource (EmbeddedResource.t_of_yojson (`Assoc fields))
410
+
| _ -> raise (Json.Of_json ("Invalid or missing content type", `Assoc fields)))
411
+
| j -> raise (Json.Of_json ("Expected object for content", j))
414
+
module CallToolResult = struct
416
+
content: content list;
418
+
meta: Json.t option;
421
+
let yojson_of_t { content; is_error; meta } =
423
+
("content", `List (List.map yojson_of_content content));
424
+
("isError", `Bool is_error);
426
+
let assoc = match meta with
427
+
| Some meta_json -> ("_meta", meta_json) :: assoc
432
+
let t_of_yojson = function
434
+
let content = match List.assoc_opt "content" fields with
435
+
| Some (`List items) -> List.map content_of_yojson items
436
+
| _ -> raise (Json.Of_json ("Missing or invalid 'content' field", `Assoc fields))
438
+
let is_error = match List.assoc_opt "isError" fields with
439
+
| Some (`Bool b) -> b
440
+
| None -> false (* Default to false if not specified *)
441
+
| _ -> raise (Json.Of_json ("Invalid 'isError' field", `Assoc fields))
443
+
let meta = List.assoc_opt "_meta" fields in
444
+
{ content; is_error; meta }
445
+
| j -> raise (Json.Of_json ("Expected object for CallToolResult", j))
448
+
(** Resource definition *)
449
+
module Resource = struct
453
+
description: string option;
454
+
mime_type: string option;
456
+
annotations: Annotated.annotation option;
459
+
let yojson_of_t { name; uri; description; mime_type; size; annotations } =
461
+
("name", `String name);
462
+
("uri", `String uri);
464
+
let assoc = match description with
465
+
| Some desc -> ("description", `String desc) :: assoc
468
+
let assoc = match mime_type with
469
+
| Some mime -> ("mimeType", `String mime) :: assoc
472
+
let assoc = match size with
473
+
| Some s -> ("size", `Int s) :: assoc
476
+
let assoc = match annotations with
477
+
| Some ann -> ("annotations", Annotated.yojson_of_annotation ann) :: assoc
482
+
let t_of_yojson = function
484
+
let name = match List.assoc_opt "name" fields with
485
+
| Some (`String s) -> s
486
+
| _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields))
488
+
let uri = match List.assoc_opt "uri" fields with
489
+
| Some (`String s) -> s
490
+
| _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
492
+
let description = match List.assoc_opt "description" fields with
493
+
| Some (`String s) -> Some s
496
+
let mime_type = match List.assoc_opt "mimeType" fields with
497
+
| Some (`String s) -> Some s
500
+
let size = match List.assoc_opt "size" fields with
501
+
| Some (`Int s) -> Some s
504
+
let annotations = match List.assoc_opt "annotations" fields with
505
+
| Some json -> Some (Annotated.annotation_of_yojson json)
508
+
{ name; uri; description; mime_type; size; annotations }
509
+
| j -> raise (Json.Of_json ("Expected object for Resource", j))
512
+
(** Resource Template definition *)
513
+
module ResourceTemplate = struct
516
+
uri_template: string;
517
+
description: string option;
518
+
mime_type: string option;
519
+
annotations: Annotated.annotation option;
522
+
let yojson_of_t { name; uri_template; description; mime_type; annotations } =
524
+
("name", `String name);
525
+
("uriTemplate", `String uri_template);
527
+
let assoc = match description with
528
+
| Some desc -> ("description", `String desc) :: assoc
531
+
let assoc = match mime_type with
532
+
| Some mime -> ("mimeType", `String mime) :: assoc
535
+
let assoc = match annotations with
536
+
| Some ann -> ("annotations", Annotated.yojson_of_annotation ann) :: assoc
541
+
let t_of_yojson = function
543
+
let name = match List.assoc_opt "name" fields with
544
+
| Some (`String s) -> s
545
+
| _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields))
547
+
let uri_template = match List.assoc_opt "uriTemplate" fields with
548
+
| Some (`String s) -> s
549
+
| _ -> raise (Json.Of_json ("Missing or invalid 'uriTemplate' field", `Assoc fields))
551
+
let description = match List.assoc_opt "description" fields with
552
+
| Some (`String s) -> Some s
555
+
let mime_type = match List.assoc_opt "mimeType" fields with
556
+
| Some (`String s) -> Some s
559
+
let annotations = match List.assoc_opt "annotations" fields with
560
+
| Some json -> Some (Annotated.annotation_of_yojson json)
563
+
{ name; uri_template; description; mime_type; annotations }
564
+
| j -> raise (Json.Of_json ("Expected object for ResourceTemplate", j))
567
+
(** Resource Reference *)
568
+
module ResourceReference = struct
573
+
let yojson_of_t { uri } =
575
+
("type", `String "ref/resource");
576
+
("uri", `String uri);
579
+
let t_of_yojson = function
581
+
let _ = match List.assoc_opt "type" fields with
582
+
| Some (`String "ref/resource") -> ()
583
+
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
585
+
let uri = match List.assoc_opt "uri" fields with
586
+
| Some (`String s) -> s
587
+
| _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields))
590
+
| j -> raise (Json.Of_json ("Expected object for ResourceReference", j))
593
+
(** Prompt Reference *)
594
+
module PromptReference = struct
599
+
let yojson_of_t { name } =
601
+
("type", `String "ref/prompt");
602
+
("name", `String name);
605
+
let t_of_yojson = function
607
+
let _ = match List.assoc_opt "type" fields with
608
+
| Some (`String "ref/prompt") -> ()
609
+
| _ -> raise (Json.Of_json ("Missing or invalid 'type' field", `Assoc fields))
611
+
let name = match List.assoc_opt "name" fields with
612
+
| Some (`String s) -> s
613
+
| _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields))
616
+
| j -> raise (Json.Of_json ("Expected object for PromptReference", j))
619
+
(** Completion support *)
620
+
module Completion = struct
622
+
module Argument = struct
628
+
let yojson_of_t { name; value } =
630
+
("name", `String name);
631
+
("value", `String value);
634
+
let t_of_yojson = function
636
+
let name = match List.assoc_opt "name" fields with
637
+
| Some (`String s) -> s
638
+
| _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields))
640
+
let value = match List.assoc_opt "value" fields with
641
+
| Some (`String s) -> s
642
+
| _ -> raise (Json.Of_json ("Missing or invalid 'value' field", `Assoc fields))
645
+
| j -> raise (Json.Of_json ("Expected object for Completion.Argument", j))
648
+
module Request = struct
649
+
type reference = [ `Prompt of PromptReference.t | `Resource of ResourceReference.t ]
652
+
argument: Argument.t;
656
+
let yojson_of_reference = function
657
+
| `Prompt p -> PromptReference.yojson_of_t p
658
+
| `Resource r -> ResourceReference.yojson_of_t r
660
+
let reference_of_yojson = function
662
+
(match List.assoc_opt "type" fields with
663
+
| Some (`String "ref/prompt") -> `Prompt (PromptReference.t_of_yojson (`Assoc fields))
664
+
| Some (`String "ref/resource") -> `Resource (ResourceReference.t_of_yojson (`Assoc fields))
665
+
| _ -> raise (Json.Of_json ("Invalid or missing reference type", `Assoc fields)))
666
+
| j -> raise (Json.Of_json ("Expected object for reference", j))
668
+
let yojson_of_t { argument; ref } =
670
+
("argument", Argument.yojson_of_t argument);
671
+
("ref", yojson_of_reference ref);
674
+
let t_of_yojson = function
676
+
let argument = match List.assoc_opt "argument" fields with
677
+
| Some json -> Argument.t_of_yojson json
678
+
| _ -> raise (Json.Of_json ("Missing argument field", `Assoc fields))
680
+
let ref = match List.assoc_opt "ref" fields with
681
+
| Some json -> reference_of_yojson json
682
+
| _ -> raise (Json.Of_json ("Missing ref field", `Assoc fields))
685
+
| j -> raise (Json.Of_json ("Expected object for Completion.Request", j))
687
+
let create ~argument ~ref =
694
+
module Result = struct
695
+
type completion = {
696
+
values: string list;
697
+
has_more: bool option;
702
+
completion: completion;
703
+
meta: Json.t option;
706
+
let yojson_of_completion { values; has_more; total } =
708
+
("values", `List (List.map (fun s -> `String s) values));
710
+
let assoc = match has_more with
711
+
| Some b -> ("hasMore", `Bool b) :: assoc
714
+
let assoc = match total with
715
+
| Some n -> ("total", `Int n) :: assoc
720
+
let completion_of_yojson = function
722
+
let values = match List.assoc_opt "values" fields with
723
+
| Some (`List items) ->
726
+
| _ -> raise (Json.Of_json ("Expected string in values array", `List items))
728
+
| _ -> raise (Json.Of_json ("Missing or invalid 'values' field", `Assoc fields))
730
+
let has_more = match List.assoc_opt "hasMore" fields with
731
+
| Some (`Bool b) -> Some b
733
+
| _ -> raise (Json.Of_json ("Invalid 'hasMore' field", `Assoc fields))
735
+
let total = match List.assoc_opt "total" fields with
736
+
| Some (`Int n) -> Some n
738
+
| _ -> raise (Json.Of_json ("Invalid 'total' field", `Assoc fields))
740
+
{ values; has_more; total }
741
+
| j -> raise (Json.Of_json ("Expected object for completion", j))
743
+
let yojson_of_t { completion; meta } =
745
+
("completion", yojson_of_completion completion);
747
+
let assoc = match meta with
748
+
| Some meta_json -> ("_meta", meta_json) :: assoc
753
+
let t_of_yojson = function
755
+
let completion = match List.assoc_opt "completion" fields with
756
+
| Some json -> completion_of_yojson json
757
+
| _ -> raise (Json.Of_json ("Missing completion field", `Assoc fields))
759
+
let meta = List.assoc_opt "_meta" fields in
760
+
{ completion; meta }
761
+
| j -> raise (Json.Of_json ("Expected object for Completion.Result", j))
763
+
let create ~completion ?meta () =
764
+
{ completion; meta }
module PromptMessage = struct
483
-
type t = { role : Role.t; content : content }
let yojson_of_t { role; content } =
488
-
("role", Role.yojson_of_t role); ("content", yojson_of_content content);
781
+
("role", Role.yojson_of_t role);
782
+
("content", yojson_of_content content);
let t_of_yojson = function
492
-
| `Assoc fields as json ->
494
-
match List.assoc_opt "role" fields with
495
-
| Some json -> Role.t_of_yojson json
496
-
| None -> Util.json_error "Missing role field" json
499
-
match List.assoc_opt "content" fields with
500
-
| Some json -> content_of_yojson json
501
-
| None -> Util.json_error "Missing content field" json
504
-
| j -> Util.json_error "Expected object for PromptMessage" j
787
+
let role = match List.assoc_opt "role" fields with
788
+
| Some json -> Role.t_of_yojson json
789
+
| None -> raise (Json.Of_json ("Missing role field", `Assoc fields))
791
+
let content = match List.assoc_opt "content" fields with
792
+
| Some json -> content_of_yojson json
793
+
| None -> raise (Json.Of_json ("Missing content field", `Assoc fields))
796
+
| j -> raise (Json.Of_json ("Expected object for PromptMessage", j))
module SamplingMessage = struct
511
-
[ `Text of TextContent.t
512
-
| `Image of ImageContent.t
513
-
| `Audio of AudioContent.t ];
802
+
content: [ `Text of TextContent.t | `Image of ImageContent.t ];
let yojson_of_t { role; content } =
806
+
let content_json = match content with
| `Text t -> TextContent.yojson_of_t t
| `Image i -> ImageContent.yojson_of_t i
521
-
| `Audio a -> AudioContent.yojson_of_t a
523
-
`Assoc [ ("role", Role.yojson_of_t role); ("content", content_json) ]
811
+
("role", Role.yojson_of_t role);
812
+
("content", content_json);
let t_of_yojson = function
526
-
| `Assoc fields as json ->
528
-
match List.assoc_opt "role" fields with
529
-
| Some json -> Role.t_of_yojson json
530
-
| None -> Util.json_error "Missing role field" json
533
-
match List.assoc_opt "content" fields with
534
-
| Some (`Assoc content_fields) -> content_fields
535
-
| _ -> Util.json_error "Missing or invalid content field" json
538
-
match List.assoc_opt "type" content_obj with
539
-
| Some (`String ty) -> ty
541
-
Util.json_error "Missing or invalid content type"
542
-
(`Assoc content_obj)
545
-
match content_type with
546
-
| "text" -> `Text (TextContent.t_of_yojson (`Assoc content_obj))
547
-
| "image" -> `Image (ImageContent.t_of_yojson (`Assoc content_obj))
548
-
| "audio" -> `Audio (AudioContent.t_of_yojson (`Assoc content_obj))
550
-
Util.json_error "Invalid content type: %s" (`Assoc content_obj)
554
-
| j -> Util.json_error "Expected object for SamplingMessage" j
817
+
let role = match List.assoc_opt "role" fields with
818
+
| Some json -> Role.t_of_yojson json
819
+
| None -> raise (Json.Of_json ("Missing role field", `Assoc fields))
821
+
let content = match List.assoc_opt "content" fields with
822
+
| Some (`Assoc content_fields) ->
823
+
(match List.assoc_opt "type" content_fields with
824
+
| Some (`String "text") -> `Text (TextContent.t_of_yojson (`Assoc content_fields))
825
+
| Some (`String "image") -> `Image (ImageContent.t_of_yojson (`Assoc content_fields))
826
+
| _ -> raise (Json.Of_json ("Invalid content type", `Assoc content_fields)))
827
+
| _ -> raise (Json.Of_json ("Missing or invalid content field", `Assoc fields))
830
+
| j -> raise (Json.Of_json ("Expected object for SamplingMessage", j))
(* Implementation info *)
module Implementation = struct
560
-
type t = { name : string; version : string }
let yojson_of_t { name; version } =
563
-
`Assoc [ ("name", `String name); ("version", `String version) ]
843
+
("name", `String name);
844
+
("version", `String version);
let t_of_yojson = function
566
-
| `Assoc fields as json ->
567
-
let name = Util.get_string_field fields "name" json in
568
-
let version = Util.get_string_field fields "version" json in
570
-
| j -> Util.json_error "Expected object for Implementation" j
849
+
let name = match List.assoc_opt "name" fields with
850
+
| Some (`String s) -> s
851
+
| _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields))
853
+
let version = match List.assoc_opt "version" fields with
854
+
| Some (`String s) -> s
855
+
| _ -> raise (Json.Of_json ("Missing or invalid 'version' field", `Assoc fields))
858
+
| j -> raise (Json.Of_json ("Expected object for Implementation", j))
(* JSONRPC Message types *)
module JSONRPCMessage = struct
576
-
type notification = { meth : Method.t; params : Json.t option }
865
+
type notification = {
867
+
params: Json.t option;
581
-
params : Json.t option;
582
-
progress_token : ProgressToken.t option;
873
+
params: Json.t option;
874
+
progress_token: ProgressToken.t option;
585
-
type response = { id : RequestId.t; result : Json.t }
591
-
data : Json.t option;
886
+
data: Json.t option;
···
600
-
let yojson_of_notification (n : notification) =
603
-
("jsonrpc", `String "2.0"); ("method", `String (Method.to_string n.meth));
607
-
match n.params with
895
+
let yojson_of_notification (n: notification) =
897
+
("jsonrpc", `String "2.0");
898
+
("method", `String n.method_);
900
+
let assoc = match n.params with
| Some params -> ("params", params) :: assoc
613
-
let yojson_of_request (r : request) =
616
-
("jsonrpc", `String "2.0");
617
-
("id", Id.yojson_of_t r.id);
618
-
("method", `String (Method.to_string r.meth));
622
-
match r.params with
906
+
let yojson_of_request (r: request) =
908
+
("jsonrpc", `String "2.0");
909
+
("id", Id.yojson_of_t r.id);
910
+
("method", `String r.method_);
912
+
let assoc = match r.params with
628
-
match r.progress_token with
632
-
[ ("progressToken", ProgressToken.yojson_of_t token) ]
634
-
("_meta", meta) :: fields
640
-
("params", params_json) :: assoc
914
+
let params_json = match params with
916
+
let fields = match r.progress_token with
918
+
let meta = `Assoc [ "progressToken", ProgressToken.yojson_of_t token ] in
919
+
("_meta", meta) :: fields
925
+
("params", params_json) :: assoc
645
-
let yojson_of_response (r : response) =
648
-
("jsonrpc", `String "2.0");
649
-
("id", Id.yojson_of_t r.id);
650
-
("result", r.result);
930
+
let yojson_of_response (r: response) =
932
+
("jsonrpc", `String "2.0");
933
+
("id", Id.yojson_of_t r.id);
934
+
("result", r.result);
653
-
let yojson_of_error (e : error) =
655
-
[ ("code", `Int e.code); ("message", `String e.message) ]
937
+
let yojson_of_error (e: error) =
938
+
let error_assoc = [
939
+
("code", `Int e.code);
940
+
("message", `String e.message);
942
+
let error_assoc = match e.data with
| Some data -> ("data", data) :: error_assoc
664
-
("jsonrpc", `String "2.0");
665
-
("id", Id.yojson_of_t e.id);
666
-
("error", `Assoc error_assoc);
947
+
("jsonrpc", `String "2.0");
948
+
("id", Id.yojson_of_t e.id);
949
+
("error", `Assoc error_assoc);
let yojson_of_t = function
| Notification n -> yojson_of_notification n
···
let notification_of_yojson = function
678
-
match List.assoc_opt "method" fields with
679
-
| Some (`String s) -> (
680
-
try Method.of_string s
681
-
with Failure msg -> Util.json_error "%s" (`String s) msg)
683
-
Util.json_error "Missing or invalid 'method' field"
686
-
let params = List.assoc_opt "params" fields in
688
-
| j -> Util.json_error "Expected object for notification" j
960
+
let method_ = match List.assoc_opt "method" fields with
961
+
| Some (`String s) -> s
962
+
| _ -> raise (Json.Of_json ("Missing or invalid 'method' field", `Assoc fields))
964
+
let params = List.assoc_opt "params" fields in
965
+
{ method_; params }
966
+
| j -> raise (Json.Of_json ("Expected object for notification", j))
let request_of_yojson = function
693
-
match List.assoc_opt "id" fields with
694
-
| Some id_json -> Id.t_of_yojson id_json
695
-
| _ -> Util.json_error "Missing or invalid 'id' field" (`Assoc fields)
698
-
match List.assoc_opt "method" fields with
699
-
| Some (`String s) -> (
700
-
try Method.of_string s
701
-
with Failure msg -> Util.json_error "%s" (`String s) msg)
703
-
Util.json_error "Missing or invalid 'method' field"
706
-
let params = List.assoc_opt "params" fields in
707
-
let progress_token =
709
-
| Some (`Assoc param_fields) -> (
710
-
match List.assoc_opt "_meta" param_fields with
711
-
| Some (`Assoc meta_fields) -> (
712
-
match List.assoc_opt "progressToken" meta_fields with
713
-
| Some token_json ->
714
-
Some (ProgressToken.t_of_yojson token_json)
719
-
{ id; meth; params; progress_token }
720
-
| j -> Util.json_error "Expected object for request" j
970
+
let id = match List.assoc_opt "id" fields with
971
+
| Some id_json -> Id.t_of_yojson id_json
972
+
| _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields))
974
+
let method_ = match List.assoc_opt "method" fields with
975
+
| Some (`String s) -> s
976
+
| _ -> raise (Json.Of_json ("Missing or invalid 'method' field", `Assoc fields))
978
+
let params = List.assoc_opt "params" fields in
979
+
let progress_token =
981
+
| Some (`Assoc param_fields) ->
982
+
(match List.assoc_opt "_meta" param_fields with
983
+
| Some (`Assoc meta_fields) ->
984
+
(match List.assoc_opt "progressToken" meta_fields with
985
+
| Some token_json -> Some (ProgressToken.t_of_yojson token_json)
990
+
{ id; method_; params; progress_token }
991
+
| j -> raise (Json.Of_json ("Expected object for request", j))
let response_of_yojson = function
725
-
match List.assoc_opt "id" fields with
726
-
| Some id_json -> Id.t_of_yojson id_json
727
-
| _ -> Util.json_error "Missing or invalid 'id' field" (`Assoc fields)
730
-
match List.assoc_opt "result" fields with
731
-
| Some result -> result
732
-
| _ -> Util.json_error "Missing 'result' field" (`Assoc fields)
735
-
| j -> Util.json_error "Expected object for response" j
995
+
let id = match List.assoc_opt "id" fields with
996
+
| Some id_json -> Id.t_of_yojson id_json
997
+
| _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields))
999
+
let result = match List.assoc_opt "result" fields with
1000
+
| Some result -> result
1001
+
| _ -> raise (Json.Of_json ("Missing 'result' field", `Assoc fields))
1004
+
| j -> raise (Json.Of_json ("Expected object for response", j))
let error_of_yojson = function
738
-
| `Assoc fields as json ->
740
-
match List.assoc_opt "id" fields with
741
-
| Some id_json -> Id.t_of_yojson id_json
742
-
| _ -> Util.json_error "Missing or invalid 'id' field" json
745
-
match List.assoc_opt "error" fields with
746
-
| Some (`Assoc error_fields) -> error_fields
747
-
| _ -> Util.json_error "Missing or invalid 'error' field" json
750
-
match List.assoc_opt "code" error with
751
-
| Some (`Int code) -> code
753
-
Util.json_error "Missing or invalid 'code' field in error"
757
-
match List.assoc_opt "message" error with
758
-
| Some (`String msg) -> msg
760
-
Util.json_error "Missing or invalid 'message' field in error"
763
-
let data = List.assoc_opt "data" error in
764
-
{ id; code; message; data }
765
-
| j -> Util.json_error "Expected object for error" j
1007
+
| `Assoc fields ->
1008
+
let id = match List.assoc_opt "id" fields with
1009
+
| Some id_json -> Id.t_of_yojson id_json
1010
+
| _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields))
1012
+
let error = match List.assoc_opt "error" fields with
1013
+
| Some (`Assoc error_fields) -> error_fields
1014
+
| _ -> raise (Json.Of_json ("Missing or invalid 'error' field", `Assoc fields))
1016
+
let code = match List.assoc_opt "code" error with
1017
+
| Some (`Int code) -> code
1018
+
| _ -> raise (Json.Of_json ("Missing or invalid 'code' field in error", `Assoc error))
1020
+
let message = match List.assoc_opt "message" error with
1021
+
| Some (`String msg) -> msg
1022
+
| _ -> raise (Json.Of_json ("Missing or invalid 'message' field in error", `Assoc error))
1024
+
let data = List.assoc_opt "data" error in
1025
+
{ id; code; message; data }
1026
+
| j -> raise (Json.Of_json ("Expected object for error", j))
771
-
match List.assoc_opt "jsonrpc" fields with
772
-
| Some (`String "2.0") -> ()
773
-
| _ -> Util.json_error "Missing or invalid 'jsonrpc' field" json
775
-
if List.mem_assoc "method" fields then
776
-
if List.mem_assoc "id" fields then Request (request_of_yojson json)
777
-
else Notification (notification_of_yojson json)
778
-
else if List.mem_assoc "result" fields then
779
-
Response (response_of_yojson json)
780
-
else if List.mem_assoc "error" fields then Error (error_of_yojson json)
781
-
else Util.json_error "Invalid JSONRPC message format" json
782
-
| j -> Util.json_error "Expected object for JSONRPC message" j
1031
+
let _jsonrpc = match List.assoc_opt "jsonrpc" fields with
1032
+
| Some (`String "2.0") -> ()
1033
+
| _ -> raise (Json.Of_json ("Missing or invalid 'jsonrpc' field", json))
1035
+
if List.mem_assoc "method" fields then
1036
+
if List.mem_assoc "id" fields then
1037
+
Request (request_of_yojson json)
1039
+
Notification (notification_of_yojson json)
1040
+
else if List.mem_assoc "result" fields then
1041
+
Response (response_of_yojson json)
1042
+
else if List.mem_assoc "error" fields then
1043
+
Error (error_of_yojson json)
1045
+
raise (Json.Of_json ("Invalid JSONRPC message format", json))
1046
+
| j -> raise (Json.Of_json ("Expected object for JSONRPC message", j))
784
-
let create_notification ?(params = None) ~meth () =
785
-
Notification { meth; params }
1048
+
let create_notification ?(params=None) ~method_ () =
1049
+
Notification { method_; params }
787
-
let create_request ?(params = None) ?(progress_token = None) ~id ~meth () =
788
-
Request { id; meth; params; progress_token }
1051
+
let create_request ?(params=None) ?(progress_token=None) ~id ~method_ () =
1052
+
Request { id; method_; params; progress_token }
790
-
let create_response ~id ~result = Response { id; result }
1054
+
let create_response ~id ~result =
1055
+
Response { id; result }
792
-
let create_error ~id ~code ~message ?(data = None) () =
1057
+
let create_error ~id ~code ~message ?(data=None) () =
Error { id; code; message; data }
···
module Initialize = struct
801
-
capabilities : Json.t; (* ClientCapabilities *)
802
-
client_info : Implementation.t;
803
-
protocol_version : string;
1066
+
capabilities: Json.t; (* ClientCapabilities *)
1067
+
client_info: Implementation.t;
1068
+
protocol_version: string;
let yojson_of_t { capabilities; client_info; protocol_version } =
809
-
("capabilities", capabilities);
810
-
("clientInfo", Implementation.yojson_of_t client_info);
811
-
("protocolVersion", `String protocol_version);
1073
+
("capabilities", capabilities);
1074
+
("clientInfo", Implementation.yojson_of_t client_info);
1075
+
("protocolVersion", `String protocol_version);
let t_of_yojson = function
815
-
| `Assoc fields as json ->
817
-
match List.assoc_opt "capabilities" fields with
818
-
| Some json -> json
819
-
| None -> Util.json_error "Missing capabilities field" json
822
-
match List.assoc_opt "clientInfo" fields with
823
-
| Some json -> Implementation.t_of_yojson json
824
-
| None -> Util.json_error "Missing clientInfo field" json
826
-
let protocol_version =
827
-
Util.get_string_field fields "protocolVersion" json
829
-
{ capabilities; client_info; protocol_version }
830
-
| j -> Util.json_error "Expected object for InitializeRequest" j
1079
+
| `Assoc fields ->
1080
+
let capabilities = match List.assoc_opt "capabilities" fields with
1081
+
| Some json -> json
1082
+
| None -> raise (Json.Of_json ("Missing capabilities field", `Assoc fields))
1084
+
let client_info = match List.assoc_opt "clientInfo" fields with
1085
+
| Some json -> Implementation.t_of_yojson json
1086
+
| None -> raise (Json.Of_json ("Missing clientInfo field", `Assoc fields))
1088
+
let protocol_version = match List.assoc_opt "protocolVersion" fields with
1089
+
| Some (`String s) -> s
1090
+
| _ -> raise (Json.Of_json ("Missing or invalid protocolVersion field", `Assoc fields))
1092
+
{ capabilities; client_info; protocol_version }
1093
+
| j -> raise (Json.Of_json ("Expected object for InitializeRequest", j))
let create ~capabilities ~client_info ~protocol_version =
{ capabilities; client_info; protocol_version }
let params = yojson_of_t t in
837
-
JSONRPCMessage.create_request ~id ~meth:Method.Initialize
838
-
~params:(Some params) ()
1100
+
JSONRPCMessage.create_request ~id ~method_:"initialize" ~params:(Some params) ()
843
-
capabilities : Json.t; (* ServerCapabilities *)
844
-
server_info : Implementation.t;
845
-
protocol_version : string;
846
-
instructions : string option;
847
-
meta : Json.t option;
1105
+
capabilities: Json.t; (* ServerCapabilities *)
1106
+
server_info: Implementation.t;
1107
+
protocol_version: string;
1108
+
instructions: string option;
1109
+
meta: Json.t option;
851
-
{ capabilities; server_info; protocol_version; instructions; meta } =
854
-
("capabilities", capabilities);
855
-
("serverInfo", Implementation.yojson_of_t server_info);
856
-
("protocolVersion", `String protocol_version);
860
-
match instructions with
1112
+
let yojson_of_t { capabilities; server_info; protocol_version; instructions; meta } =
1114
+
("capabilities", capabilities);
1115
+
("serverInfo", Implementation.yojson_of_t server_info);
1116
+
("protocolVersion", `String protocol_version);
1118
+
let assoc = match instructions with
| Some instr -> ("instructions", `String instr) :: assoc
865
-
match meta with Some meta -> ("_meta", meta) :: assoc | None -> assoc
1122
+
let assoc = match meta with
1123
+
| Some meta -> ("_meta", meta) :: assoc
let t_of_yojson = function
870
-
| `Assoc fields as json ->
872
-
match List.assoc_opt "capabilities" fields with
873
-
| Some json -> json
874
-
| None -> Util.json_error "Missing capabilities field" json
877
-
match List.assoc_opt "serverInfo" fields with
878
-
| Some json -> Implementation.t_of_yojson json
879
-
| None -> Util.json_error "Missing serverInfo field" json
881
-
let protocol_version =
882
-
Util.get_string_field fields "protocolVersion" json
885
-
Util.get_optional_string_field fields "instructions"
887
-
let meta = List.assoc_opt "_meta" fields in
888
-
{ capabilities; server_info; protocol_version; instructions; meta }
889
-
| j -> Util.json_error "Expected object for InitializeResult" j
1129
+
| `Assoc fields ->
1130
+
let capabilities = match List.assoc_opt "capabilities" fields with
1131
+
| Some json -> json
1132
+
| None -> raise (Json.Of_json ("Missing capabilities field", `Assoc fields))
1134
+
let server_info = match List.assoc_opt "serverInfo" fields with
1135
+
| Some json -> Implementation.t_of_yojson json
1136
+
| None -> raise (Json.Of_json ("Missing serverInfo field", `Assoc fields))
1138
+
let protocol_version = match List.assoc_opt "protocolVersion" fields with
1139
+
| Some (`String s) -> s
1140
+
| _ -> raise (Json.Of_json ("Missing or invalid protocolVersion field", `Assoc fields))
1142
+
let instructions = match List.assoc_opt "instructions" fields with
1143
+
| Some (`String s) -> Some s
1146
+
let meta = List.assoc_opt "_meta" fields in
1147
+
{ capabilities; server_info; protocol_version; instructions; meta }
1148
+
| j -> raise (Json.Of_json ("Expected object for InitializeResult", j))
891
-
let create ~capabilities ~server_info ~protocol_version ?instructions ?meta
1150
+
let create ~capabilities ~server_info ~protocol_version ?instructions ?meta () =
{ capabilities; server_info; protocol_version; instructions; meta }
···
module Initialized = struct
module Notification = struct
902
-
type t = { meta : Json.t option }
1161
+
meta: Json.t option;
let yojson_of_t { meta } =
907
-
match meta with Some meta -> ("_meta", meta) :: assoc | None -> assoc
1166
+
let assoc = match meta with
1167
+
| Some meta -> ("_meta", meta) :: assoc
let t_of_yojson = function
913
-
let meta = List.assoc_opt "_meta" fields in
915
-
| j -> Util.json_error "Expected object for InitializedNotification" j
1174
+
let meta = List.assoc_opt "_meta" fields in
1176
+
| j -> raise (Json.Of_json ("Expected object for InitializedNotification", j))
let create ?meta () = { meta }
921
-
match yojson_of_t t with `Assoc [] -> None | json -> Some json
1181
+
let params = match yojson_of_t t with
1182
+
| `Assoc [] -> None
1183
+
| json -> Some json
923
-
JSONRPCMessage.create_notification ~meth:Method.Initialized ~params ()
1185
+
JSONRPCMessage.create_notification ~method_:"notifications/initialized" ~params ()
(* Export the main interface for using the MCP protocol *)
929
-
let parse_message json = JSONRPCMessage.t_of_yojson json
931
-
let create_notification ?(params = None) ~meth () =
932
-
JSONRPCMessage.create_notification ~params ~meth ()
934
-
let create_request ?(params = None) ?(progress_token = None) ~id ~meth () =
935
-
JSONRPCMessage.create_request ~params ~progress_token ~id ~meth ()
1191
+
let parse_message json =
1192
+
JSONRPCMessage.t_of_yojson json
1194
+
let create_notification = JSONRPCMessage.create_notification
1195
+
let create_request = JSONRPCMessage.create_request
let create_response = JSONRPCMessage.create_response
let create_error = JSONRPCMessage.create_error
940
-
(* Content type constructors *)
941
-
let make_text_content text = Text TextContent.{ text; annotations = None }
943
-
let make_image_content data mime_type =
944
-
Image ImageContent.{ data; mime_type; annotations = None }
946
-
let make_audio_content data mime_type =
947
-
Audio AudioContent.{ data; mime_type; annotations = None }
949
-
let make_resource_text_content uri text mime_type =
953
-
resource = `Text TextResourceContents.{ uri; text; mime_type };
954
-
annotations = None;
957
-
let make_resource_blob_content uri blob mime_type =
961
-
resource = `Blob BlobResourceContents.{ uri; blob; mime_type };
962
-
annotations = None;
1199
+
(* Helper functions *)
1200
+
let create_completion_request ~id ~argument ~ref =
1201
+
let params = Completion.Request.to_params { argument; ref } in
1202
+
create_request ~id ~method_:"completion/complete" ~params:(Some params) ()
1204
+
let create_completion_response ~id ~values ?(has_more=None) ?(total=None) ?(meta=None) () =
1205
+
let completion = { Completion.Result.values; has_more; total } in
1206
+
let result = Completion.Result.to_result { completion; meta } in
1207
+
create_response ~id ~result