this repo has no description
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add AudioContent, Tool, and CallToolResult modules

- Added ErrorCode module with standard JSON-RPC error codes
- Added AudioContent module for audio content support
- Added Tool module for defining tools that can be called by clients
- Added CallToolResult module for handling tool call results
- Updated content type to include Audio content

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

+175
+126
lib/mcp.ml
··· 1 1 open Jsonrpc 2 2 3 + (* Standard error codes *) 4 + module ErrorCode = struct 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 13 + end 14 + 3 15 (* Common types *) 4 16 5 17 module Role = struct ··· 157 169 | j -> raise (Json.Of_json ("Expected object for ImageContent", j)) 158 170 end 159 171 172 + module AudioContent = struct 173 + type t = { 174 + data: string; 175 + mime_type: string; 176 + annotations: Annotated.annotation option; 177 + } 178 + 179 + let yojson_of_t { data; mime_type; annotations } = 180 + let assoc = [ 181 + ("data", `String data); 182 + ("mimeType", `String mime_type); 183 + ("type", `String "audio"); 184 + ] in 185 + let assoc = match annotations with 186 + | Some annotations -> ("annotations", Annotated.yojson_of_annotation annotations) :: assoc 187 + | None -> assoc 188 + in 189 + `Assoc assoc 190 + 191 + let t_of_yojson = function 192 + | `Assoc fields -> 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)) 196 + in 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)) 200 + in 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)) 204 + in 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)) 208 + end 209 + 160 210 module ResourceContents = struct 161 211 type t = { 162 212 uri: string; ··· 301 351 | j -> raise (Json.Of_json ("Expected object for EmbeddedResource", j)) 302 352 end 303 353 354 + (** Tool definition *) 355 + module Tool = struct 356 + type t = { 357 + name: string; 358 + description: string option; 359 + input_schema: Json.t; 360 + } 361 + 362 + let yojson_of_t { name; description; input_schema } = 363 + let assoc = [ 364 + ("name", `String name); 365 + ("inputSchema", input_schema); 366 + ] in 367 + let assoc = match description with 368 + | Some desc -> ("description", `String desc) :: assoc 369 + | None -> assoc 370 + in 371 + `Assoc assoc 372 + 373 + let t_of_yojson = function 374 + | `Assoc fields -> 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)) 378 + in 379 + let description = match List.assoc_opt "description" fields with 380 + | Some (`String s) -> Some s 381 + | _ -> None 382 + in 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)) 386 + in 387 + { name; description; input_schema } 388 + | j -> raise (Json.Of_json ("Expected object for Tool", j)) 389 + end 390 + 304 391 type content = 305 392 | Text of TextContent.t 306 393 | Image of ImageContent.t 394 + | Audio of AudioContent.t 307 395 | Resource of EmbeddedResource.t 308 396 309 397 let yojson_of_content = function 310 398 | Text t -> TextContent.yojson_of_t t 311 399 | Image i -> ImageContent.yojson_of_t i 400 + | Audio a -> AudioContent.yojson_of_t a 312 401 | Resource r -> EmbeddedResource.yojson_of_t r 313 402 314 403 let content_of_yojson = function ··· 316 405 (match List.assoc_opt "type" fields with 317 406 | Some (`String "text") -> Text (TextContent.t_of_yojson (`Assoc fields)) 318 407 | Some (`String "image") -> Image (ImageContent.t_of_yojson (`Assoc fields)) 408 + | Some (`String "audio") -> Audio (AudioContent.t_of_yojson (`Assoc fields)) 319 409 | Some (`String "resource") -> Resource (EmbeddedResource.t_of_yojson (`Assoc fields)) 320 410 | _ -> raise (Json.Of_json ("Invalid or missing content type", `Assoc fields))) 321 411 | j -> raise (Json.Of_json ("Expected object for content", j)) 412 + 413 + (** Tool result *) 414 + module CallToolResult = struct 415 + type t = { 416 + content: content list; 417 + is_error: bool; 418 + meta: Json.t option; 419 + } 420 + 421 + let yojson_of_t { content; is_error; meta } = 422 + let assoc = [ 423 + ("content", `List (List.map yojson_of_content content)); 424 + ("isError", `Bool is_error); 425 + ] in 426 + let assoc = match meta with 427 + | Some meta_json -> ("_meta", meta_json) :: assoc 428 + | None -> assoc 429 + in 430 + `Assoc assoc 431 + 432 + let t_of_yojson = function 433 + | `Assoc fields -> 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)) 437 + in 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)) 442 + in 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)) 446 + end 322 447 323 448 (* Message types *) 324 449 ··· 411 536 end 412 537 413 538 (* JSONRPC Message types *) 539 + 414 540 415 541 module JSONRPCMessage = struct 416 542 type notification = {
+49
lib/mcp.mli
··· 2 2 3 3 open Jsonrpc 4 4 5 + (** Standard error codes *) 6 + module ErrorCode : sig 7 + val parse_error : int 8 + val invalid_request : int 9 + val method_not_found : int 10 + val invalid_params : int 11 + val internal_error : int 12 + val resource_not_found : int 13 + val server_error_start : int 14 + val server_error_end : int 15 + end 16 + 5 17 (** Common types *) 6 18 7 19 (** Roles for conversation participants *) ··· 77 89 val t_of_yojson : Json.t -> t 78 90 end 79 91 92 + (** Audio content *) 93 + module AudioContent : sig 94 + type t = { 95 + data: string; 96 + mime_type: string; 97 + annotations: Annotated.annotation option; 98 + } 99 + 100 + val yojson_of_t : t -> Json.t 101 + val t_of_yojson : Json.t -> t 102 + end 103 + 80 104 (** Base resource contents *) 81 105 module ResourceContents : sig 82 106 type t = { ··· 127 151 type content = 128 152 | Text of TextContent.t 129 153 | Image of ImageContent.t 154 + | Audio of AudioContent.t 130 155 | Resource of EmbeddedResource.t 131 156 132 157 val yojson_of_content : content -> Json.t ··· 263 288 val create : ?meta:Json.t -> unit -> t 264 289 val to_jsonrpc : t -> JSONRPCMessage.t 265 290 end 291 + end 292 + 293 + (** Tool definition *) 294 + module Tool : sig 295 + type t = { 296 + name: string; 297 + description: string option; 298 + input_schema: Json.t; 299 + } 300 + 301 + val yojson_of_t : t -> Json.t 302 + val t_of_yojson : Json.t -> t 303 + end 304 + 305 + (** Tool result *) 306 + module CallToolResult : sig 307 + type t = { 308 + content: content list; 309 + is_error: bool; 310 + meta: Json.t option; 311 + } 312 + 313 + val yojson_of_t : t -> Json.t 314 + val t_of_yojson : Json.t -> t 266 315 end 267 316 268 317 (** Parse a JSON message into an MCP message *)