Model Context Protocol in OCaml
1(** MCP - Model Context Protocol implementation 2 3 The Model Context Protocol (MCP) is a standardized protocol for AI agents to 4 exchange context with servers. This module provides the core OCaml 5 implementation of MCP including all message types, content representations, 6 and serialization functionality. 7 8 MCP Architecture: 9 - Uses JSON-RPC 2.0 as its underlying message format with UTF-8 encoding 10 - Follows a client-server model where clients (often LLM-integrated 11 applications) communicate with MCP servers 12 - Supports multiple transport methods including stdio and streamable HTTP 13 - Implements a three-phase connection lifecycle: initialization, operation, 14 and shutdown 15 - Provides capability negotiation during initialization to determine 16 available features 17 - Offers four primary context exchange mechanisms: 1. Resources: 18 Server-exposed data that provides context to language models 2. Tools: 19 Server-exposed functionality that can be invoked by language models 3. 20 Prompts: Server-defined templates for structuring interactions with models 21 4. Sampling: Client-exposed ability to generate completions from LLMs 22 - Supports multimodal content types: text, images, audio, and embedded 23 resources 24 - Includes standardized error handling with defined error codes 25 26 This implementation follows Protocol Revision 2025-03-26. *) 27 28open Jsonrpc 29 30(** Utility functions for JSON parsing *) 31module Util : sig 32 val json_error : ('a, unit, string, 'b) format4 -> Json.t -> 'a 33 (** Helper to raise a Json.Of_json exception with formatted message 34 @param fmt Format string for the error message 35 @param json JSON value to include in the exception 36 @return Never returns, always raises an exception 37 @raise Json.Of_json with the formatted message and JSON value *) 38 39 val get_string_field : (string * Json.t) list -> string -> Json.t -> string 40 (** Extract a string field from JSON object or raise an error 41 @param fields Assoc list of fields from JSON object 42 @param name Field name to extract 43 @param json Original JSON for error context 44 @return The string value of the field 45 @raise Json.Of_json if the field is missing or not a string *) 46 47 val get_optional_string_field : 48 (string * Json.t) list -> string -> string option 49 (** Extract an optional string field from JSON object 50 @param fields Assoc list of fields from JSON object 51 @param name Field name to extract 52 @return Some string if present and a string, None if missing 53 @raise Json.Of_json if the field exists but is not a string *) 54 55 val get_int_field : (string * Json.t) list -> string -> Json.t -> int 56 (** Extract an int field from JSON object or raise an error 57 @param fields Assoc list of fields from JSON object 58 @param name Field name to extract 59 @param json Original JSON for error context 60 @return The int value of the field 61 @raise Json.Of_json if the field is missing or not an int *) 62 63 val get_float_field : (string * Json.t) list -> string -> Json.t -> float 64 (** Extract a float field from JSON object or raise an error 65 @param fields Assoc list of fields from JSON object 66 @param name Field name to extract 67 @param json Original JSON for error context 68 @return The float value of the field 69 @raise Json.Of_json if the field is missing or not a float *) 70 71 val get_bool_field : (string * Json.t) list -> string -> Json.t -> bool 72 (** Extract a boolean field from JSON object or raise an error 73 @param fields Assoc list of fields from JSON object 74 @param name Field name to extract 75 @param json Original JSON for error context 76 @return The boolean value of the field 77 @raise Json.Of_json if the field is missing or not a boolean *) 78 79 val get_object_field : 80 (string * Json.t) list -> string -> Json.t -> (string * Json.t) list 81 (** Extract an object field from JSON object or raise an error 82 @param fields Assoc list of fields from JSON object 83 @param name Field name to extract 84 @param json Original JSON for error context 85 @return The object as an assoc list 86 @raise Json.Of_json if the field is missing or not an object *) 87 88 val get_list_field : (string * Json.t) list -> string -> Json.t -> Json.t list 89 (** Extract a list field from JSON object or raise an error 90 @param fields Assoc list of fields from JSON object 91 @param name Field name to extract 92 @param json Original JSON for error context 93 @return The list items 94 @raise Json.Of_json if the field is missing or not a list *) 95 96 val verify_string_field : 97 (string * Json.t) list -> string -> string -> Json.t -> unit 98 (** Verify a specific string value in a field 99 @param fields Assoc list of fields from JSON object 100 @param name Field name to check 101 @param expected_value The expected string value 102 @param json Original JSON for error context 103 @raise Json.Of_json if the field is missing or not equal to expected_value 104 *) 105end 106 107(** Error codes for JSON-RPC *) 108module ErrorCode : sig 109 (** Standard JSON-RPC error codes with MCP-specific additions *) 110 type t = 111 | ParseError (** -32700 - Invalid JSON *) 112 | InvalidRequest (** -32600 - Invalid JSON-RPC request *) 113 | MethodNotFound (** -32601 - Method not available *) 114 | InvalidParams (** -32602 - Invalid method parameters *) 115 | InternalError (** -32603 - Internal JSON-RPC error *) 116 | ResourceNotFound 117 (** -32002 - Custom MCP error: requested resource not found *) 118 | AuthRequired (** -32001 - Custom MCP error: authentication required *) 119 | CustomError of int (** For any other error codes *) 120 121 val to_int : t -> int 122 (** Convert the error code to its integer representation 123 @param code The error code to convert 124 @return The integer error code as defined in the JSON-RPC spec *) 125 126 val to_message : t -> string 127 (** Get error message for standard error codes 128 @param code The error code to get message for 129 @return A standard message for the error code *) 130end 131 132(** MCP Protocol Methods - Algebraic data type representing all MCP methods *) 133module Method : sig 134 (** Method type representing all MCP protocol methods *) 135 type t = 136 (* Initialization and lifecycle methods *) 137 | Initialize (** Start the MCP lifecycle *) 138 | Initialized (** Signal readiness after initialization *) 139 (* Resource methods *) 140 | ResourcesList (** Discover available resources *) 141 | ResourcesRead (** Retrieve resource contents *) 142 | ResourceTemplatesList (** List available resource templates *) 143 | ResourcesSubscribe (** Subscribe to resource changes *) 144 | ResourcesListChanged (** Resource list has changed *) 145 | ResourcesUpdated (** Resource has been updated *) 146 (* Tool methods *) 147 | ToolsList (** Discover available tools *) 148 | ToolsCall (** Invoke a tool *) 149 | ToolsListChanged (** Tool list has changed *) 150 (* Prompt methods *) 151 | PromptsList (** Discover available prompts *) 152 | PromptsGet (** Retrieve a prompt template with arguments *) 153 | PromptsListChanged (** Prompt list has changed *) 154 (* Progress notifications *) 155 | Progress (** Progress update for long-running operations *) 156 157 val to_string : t -> string 158 (** Convert method type to string representation 159 @param meth The method to convert 160 @return 161 The string representation of the method (e.g., "initialize", 162 "resources/list") *) 163 164 val of_string : string -> t 165 (** Convert string to method type 166 @param s The string representation of the method 167 @return The corresponding method type 168 @raise Failure if the string is not a valid MCP method *) 169end 170 171(** Common types *) 172 173(** Roles for conversation participants *) 174module Role : sig 175 type t = [ `User | `Assistant ] 176 (** Role represents conversation participants in MCP messages. Roles can be 177 either 'user' or 'assistant', determining the source of each message in a 178 conversation. *) 179 180 include Json.Jsonable.S with type t := t 181end 182 183(** Progress tokens for long-running operations *) 184module ProgressToken : sig 185 type t = [ `String of string | `Int of int ] 186 (** Progress tokens identify long-running operations and enable servers to 187 provide progress updates to clients. This is used to track operations that 188 may take significant time to complete. *) 189 190 include Json.Jsonable.S with type t := t 191end 192 193(** Request IDs *) 194module RequestId : sig 195 type t = [ `String of string | `Int of int ] 196 (** Request IDs uniquely identify JSON-RPC requests, allowing responses to be 197 correlated with their originating requests. They can be either string or 198 integer values. *) 199 200 include Json.Jsonable.S with type t := t 201end 202 203(** Cursors for pagination *) 204module Cursor : sig 205 type t = string 206 (** Cursors enable pagination in list operations for resources, tools, and 207 prompts. When a server has more items than can be returned in a single 208 response, it provides a cursor for the client to retrieve subsequent 209 pages. *) 210 211 include Json.Jsonable.S with type t := t 212end 213 214(** Annotations for objects *) 215module Annotated : sig 216 type t = { annotations : annotation option } 217 (** Annotations provide metadata for content objects, allowing role-specific 218 targeting and priority settings. *) 219 220 and annotation = { 221 audience : Role.t list option; 222 (** Optional list of roles that should receive this content *) 223 priority : float option; (** Optional priority value for this content *) 224 } 225 226 include Json.Jsonable.S with type t := t 227end 228 229(** Text content - Core textual message representation in MCP *) 230module TextContent : sig 231 type t = { 232 text : string; (** The actual text content as a UTF-8 encoded string *) 233 annotations : Annotated.annotation option; 234 (** Optional annotations for audience targeting and priority. 235 Annotations can restrict content visibility to specific roles 236 (user/assistant) and indicate relative importance of different 237 content elements. *) 238 } 239 (** TextContent represents plain text messages in MCP conversations. This is 240 the most common content type used for natural language interactions 241 between users and assistants. Text content is used in prompts, tool 242 results, and model responses. 243 244 In JSON-RPC, this is represented as: 245 {v 246 { 247 "type": "text", 248 "text": "The text content of the message" 249 } 250 v} 251 252 For security, implementations must sanitize text content to prevent 253 injection attacks or unauthorized access to resources. *) 254 255 include Json.Jsonable.S with type t := t 256end 257 258(** Image content - Visual data representation in MCP *) 259module ImageContent : sig 260 type t = { 261 data : string; 262 (** Base64-encoded image data. All binary image data must be encoded 263 using standard base64 encoding (RFC 4648) to safely transmit within 264 JSON. *) 265 mime_type : string; 266 (** MIME type of the image (e.g., "image/png", "image/jpeg", 267 "image/gif", "image/svg+xml"). This field is required and must 268 accurately represent the image format to ensure proper handling by 269 clients. *) 270 annotations : Annotated.annotation option; 271 (** Optional annotations for audience targeting and priority. 272 Annotations can restrict content visibility to specific roles 273 (user/assistant) and indicate relative importance of different 274 content elements. *) 275 } 276 (** ImageContent enables including visual information in MCP messages, 277 supporting multimodal interactions where visual context is important. 278 279 Images can be used in several scenarios: 280 - As user inputs for visual understanding tasks 281 - As context for generating descriptions or analysis 282 - As outputs from tools that generate visualizations 283 - As part of prompt templates with visual components 284 285 In JSON-RPC, this is represented as: 286 {v 287 { 288 "type": "image", 289 "data": "base64-encoded-image-data", 290 "mimeType": "image/png" 291 } 292 v} 293 294 The data MUST be base64-encoded to ensure safe transmission in JSON. 295 Common mime types include image/png, image/jpeg, image/gif, and 296 image/svg+xml. *) 297 298 include Json.Jsonable.S with type t := t 299end 300 301(** Audio content - Sound data representation in MCP *) 302module AudioContent : sig 303 type t = { 304 data : string; 305 (** Base64-encoded audio data. All binary audio data must be encoded 306 using standard base64 encoding (RFC 4648) to safely transmit within 307 JSON. *) 308 mime_type : string; 309 (** MIME type of the audio (e.g., "audio/wav", "audio/mp3", "audio/ogg", 310 "audio/mpeg"). This field is required and must accurately represent 311 the audio format to ensure proper handling by clients. *) 312 annotations : Annotated.annotation option; 313 (** Optional annotations for audience targeting and priority. 314 Annotations can restrict content visibility to specific roles 315 (user/assistant) and indicate relative importance of different 316 content elements. *) 317 } 318 (** AudioContent enables including audio information in MCP messages, 319 supporting multimodal interactions where audio context is important. 320 321 Audio can be used in several scenarios: 322 - As user inputs for speech recognition or audio analysis 323 - As context for transcription or sound classification tasks 324 - As outputs from tools that generate audio samples 325 - As part of prompt templates with audio components 326 327 In JSON-RPC, this is represented as: 328 {v 329 { 330 "type": "audio", 331 "data": "base64-encoded-audio-data", 332 "mimeType": "audio/wav" 333 } 334 v} 335 336 The data MUST be base64-encoded to ensure safe transmission in JSON. 337 Common mime types include audio/wav, audio/mp3, audio/ogg, and audio/mpeg. 338 *) 339 340 include Json.Jsonable.S with type t := t 341end 342 343(** Base resource contents - Core resource metadata in MCP *) 344module ResourceContents : sig 345 type t = { 346 uri : string; 347 (** URI that uniquely identifies the resource. 348 349 Resources use standard URI schemes including: 350 - file:// - For filesystem-like resources 351 - https:// - For web-accessible resources 352 - git:// - For version control integration 353 354 The URI serves as a stable identifier even if the underlying content 355 changes. *) 356 mime_type : string option; 357 (** Optional MIME type of the resource content to aid in client 358 rendering. Common MIME types include text/plain, application/json, 359 image/png, etc. For directories, the XDG MIME type inode/directory 360 may be used. *) 361 } 362 (** ResourceContents provides basic metadata for resources in MCP. 363 364 Resources are server-exposed data that provides context to language 365 models, such as files, database schemas, or application-specific 366 information. Each resource is uniquely identified by a URI. 367 368 The MCP resources architecture is designed to be application-driven, with 369 host applications determining how to incorporate context based on their 370 needs. 371 372 In the protocol, resources are discovered via the 'resources/list' 373 endpoint and retrieved via the 'resources/read' endpoint. Servers that 374 support resources must declare the 'resources' capability during 375 initialization. *) 376 377 include Json.Jsonable.S with type t := t 378end 379 380(** Text resource contents - Textual resource data *) 381module TextResourceContents : sig 382 type t = { 383 uri : string; 384 (** URI that uniquely identifies the resource. This URI can be 385 referenced in subsequent requests to fetch updates. *) 386 text : string; 387 (** The actual text content of the resource as a UTF-8 encoded string. 388 This may be sanitized by the server to remove sensitive information. 389 *) 390 mime_type : string option; 391 (** Optional MIME type of the text content to aid in client rendering. 392 Common text MIME types include: text/plain, text/markdown, 393 text/x-python, application/json, text/html, text/csv, etc. *) 394 } 395 (** TextResourceContents represents a text-based resource in MCP. 396 397 Text resources are used for sharing code snippets, documentation, logs, 398 configuration files, and other textual information with language models. 399 400 The server handles access control and security, ensuring that only 401 authorized resources are shared with clients. 402 403 In JSON-RPC, this is represented as: 404 {v 405 { 406 "uri": "file:///example.txt", 407 "mimeType": "text/plain", 408 "text": "Resource content" 409 } 410 v} *) 411 412 include Json.Jsonable.S with type t := t 413end 414 415(** Binary resource contents - Binary resource data *) 416module BlobResourceContents : sig 417 type t = { 418 uri : string; 419 (** URI that uniquely identifies the resource. This URI can be 420 referenced in subsequent requests to fetch updates. *) 421 blob : string; 422 (** Base64-encoded binary data using standard base64 encoding (RFC 423 4648). This encoding ensures that binary data can be safely 424 transmitted in JSON. *) 425 mime_type : string option; 426 (** Optional MIME type of the binary content to aid in client rendering. 427 Common binary MIME types include: image/png, image/jpeg, 428 application/pdf, audio/wav, video/mp4, application/octet-stream, 429 etc. *) 430 } 431 (** BlobResourceContents represents a binary resource in MCP. 432 433 Binary resources allow sharing non-textual data like images, audio files, 434 PDFs, and other binary formats with language models that support 435 processing such content. 436 437 In JSON-RPC, this is represented as: 438 {v 439 { 440 "uri": "file:///example.png", 441 "mimeType": "image/png", 442 "blob": "base64-encoded-data" 443 } 444 v} 445 446 Binary data MUST be properly base64-encoded to ensure safe transmission in 447 JSON payloads. *) 448 449 include Json.Jsonable.S with type t := t 450end 451 452(** Embedded resource - Resource included directly in messages *) 453module EmbeddedResource : sig 454 type t = { 455 resource : 456 [ `Text of TextResourceContents.t | `Blob of BlobResourceContents.t ]; 457 (** The resource content, either as text or binary blob. *) 458 annotations : Annotated.annotation option; 459 (** Optional annotations for audience targeting and priority. 460 Annotations can restrict resource visibility to specific roles 461 (user/assistant) and indicate relative importance of different 462 content elements. *) 463 } 464 (** EmbeddedResource allows referencing server-side resources directly in MCP 465 messages, enabling seamless incorporation of managed content. 466 467 Embedded resources can be included in: 468 - Tool results to provide rich context 469 - Prompt templates to include reference materials 470 - Messages to provide additional context to language models 471 472 In contrast to direct content (TextContent, ImageContent, AudioContent), 473 embedded resources have the advantage of being persistently stored on the 474 server with a stable URI, allowing later retrieval and updates through the 475 resources API. 476 477 For example, a tool might return an embedded resource containing a chart 478 or a large dataset that the client can later reference or update. *) 479 480 include Json.Jsonable.S with type t := t 481end 482 483(** Content type used in messages - Unified multimodal content representation in 484 MCP *) 485type content = 486 | Text of TextContent.t 487 (** Text content for natural language messages. This is the most common 488 content type for user-assistant interactions. *) 489 | Image of ImageContent.t 490 (** Image content for visual data. Used for sharing visual context in 491 multimodal conversations. *) 492 | Audio of AudioContent.t 493 (** Audio content for audio data. Used for sharing audio context in 494 multimodal conversations. *) 495 | Resource of EmbeddedResource.t 496 (** Resource content for referencing server-side resources. Used for 497 incorporating managed server content with stable URIs. *) 498 499val yojson_of_content : content -> Json.t 500(** Convert content to Yojson representation 501 @param content The content to convert 502 @return JSON representation of the content *) 503 504val content_of_yojson : Json.t -> content 505(** Convert Yojson representation to content 506 @param json JSON representation of content 507 @return Parsed content object *) 508 509(** Message for prompts - Template messages in the MCP prompts feature *) 510module PromptMessage : sig 511 type t = { 512 role : Role.t; 513 (** The role of the message sender (user or assistant). Prompt templates 514 typically alternate between user and assistant messages to create a 515 conversation structure. *) 516 content : content; 517 (** The message content, which can be text, image, audio, or resource. 518 This unified content type supports rich multimodal prompts. *) 519 } 520 (** PromptMessage represents a message in an MCP prompt template, containing a 521 role and content which can be customized with arguments. 522 523 Prompt messages are part of prompt templates exposed by servers through 524 the prompts/get endpoint. They define structured conversation templates 525 that can be instantiated with user-provided arguments. 526 527 The prompt feature is designed to be user-controlled, with prompts 528 typically exposed through UI elements like slash commands that users can 529 explicitly select. 530 531 In JSON-RPC, prompt messages are represented as: 532 {v 533 { 534 "role": "user", 535 "content": { 536 "type": "text", 537 "text": "Please review this code: ${code}" 538 } 539 } 540 v} 541 542 Where $code would be replaced with a user-provided argument. *) 543 544 include Json.Jsonable.S with type t := t 545end 546 547(** Message for sampling - Messages used in LLM completion requests *) 548module SamplingMessage : sig 549 type t = { 550 role : Role.t; 551 (** The role of the message sender (user or assistant). Typically, a 552 sampling request will contain multiple messages representing a 553 conversation history, with alternating roles. *) 554 content : 555 [ `Text of TextContent.t 556 | `Image of ImageContent.t 557 | `Audio of AudioContent.t ]; 558 (** The message content, restricted to text, image, or audio (no 559 resources). Resources are not included since sampling messages 560 represent the actual context window for the LLM, not template 561 definitions. *) 562 } 563 (** SamplingMessage represents a message in an MCP sampling request, used for 564 AI model generation based on a prompt. 565 566 The sampling feature allows clients to expose language model capabilities 567 to servers, enabling servers to request completions from the client's LLM. 568 This is effectively the reverse of the normal MCP flow, with the server 569 requesting generative capabilities from the client. 570 571 Sampling messages differ from prompt messages in that they don't support 572 embedded resources, as they represent the actual context window being sent 573 to the LLM rather than template definitions. 574 575 Clients that support sampling must declare the 'sampling' capability 576 during initialization. *) 577 578 include Json.Jsonable.S with type t := t 579end 580 581(** Implementation information *) 582module Implementation : sig 583 type t = { 584 name : string; (** Name of the implementation *) 585 version : string; (** Version of the implementation *) 586 } 587 (** Implementation provides metadata about client and server implementations, 588 used during the initialization phase to identify each party. *) 589 590 include Json.Jsonable.S with type t := t 591end 592 593(** JSONRPC message types - Core message protocol for MCP 594 595 MCP uses JSON-RPC 2.0 as its underlying messaging protocol. All MCP messages 596 are encoded as JSON-RPC 2.0 messages with UTF-8 encoding, following the 597 standard JSON-RPC message formats with some MCP-specific extensions. 598 599 MCP defines four message types: 1. Notifications: One-way messages that 600 don't expect a response 2. Requests: Messages that expect a corresponding 601 response 3. Responses: Replies to requests with successful results 4. 602 Errors: Replies to requests with error information 603 604 These can be transported over multiple transport mechanisms: 605 - stdio: Communication over standard input/output 606 - Streamable HTTP: HTTP POST/GET with SSE for server streaming 607 - Custom transports: Implementation-specific transports 608 609 Messages may be sent individually or as part of a JSON-RPC batch. *) 610module JSONRPCMessage : sig 611 type notification = { 612 meth : Method.t; 613 (** Method for the notification, using the Method.t type to ensure type 614 safety. Examples: Method.Initialized, Method.ResourcesUpdated *) 615 params : Json.t option; 616 (** Optional parameters for the notification as arbitrary JSON. The 617 structure depends on the specific notification method. *) 618 } 619 (** Notification represents a JSON-RPC notification (one-way message without a 620 response). 621 622 Notifications are used for events that don't require a response, such as: 623 - The 'initialized' notification completing initialization 624 - Resource change notifications 625 - Progress updates for long-running operations 626 - List changed notifications for tools, resources, and prompts 627 628 In JSON-RPC, notifications are identified by the absence of an 'id' field: 629 {v 630 { 631 "jsonrpc": "2.0", 632 "method": "notifications/resources/updated", 633 "params": { 634 "uri": "file:///project/src/main.rs" 635 } 636 } 637 v} *) 638 639 type request = { 640 id : RequestId.t; 641 (** Unique identifier for the request, which will be echoed in the 642 response. This can be a string or integer and should be unique 643 within the session. *) 644 meth : Method.t; 645 (** Method for the request, using the Method.t type to ensure type 646 safety. Examples: Method.Initialize, Method.ResourcesRead, 647 Method.ToolsCall *) 648 params : Json.t option; 649 (** Optional parameters for the request as arbitrary JSON. The structure 650 depends on the specific request method. *) 651 progress_token : ProgressToken.t option; 652 (** Optional progress token for long-running operations. If provided, 653 the server can send progress notifications using this token to 654 inform the client about the operation's status. *) 655 } 656 (** Request represents a JSON-RPC request that expects a response. 657 658 Requests are used for operations that require a response, such as: 659 - Initialization 660 - Listing resources, tools, or prompts 661 - Reading resources 662 - Calling tools 663 - Getting prompts 664 665 In JSON-RPC, requests include an 'id' field that correlates with the 666 response: 667 {v 668 { 669 "jsonrpc": "2.0", 670 "id": 1, 671 "method": "resources/read", 672 "params": { 673 "uri": "file:///project/src/main.rs" 674 } 675 } 676 v} *) 677 678 type response = { 679 id : RequestId.t; 680 (** ID matching the original request, allowing clients to correlate 681 responses with their originating requests, especially important when 682 multiple requests are in flight. *) 683 result : Json.t; 684 (** Result of the successful request as arbitrary JSON. The structure 685 depends on the specific request method that was called. *) 686 } 687 (** Response represents a successful JSON-RPC response to a request. 688 689 Responses are sent in reply to requests and contain the successful result. 690 Each response must include the same ID as its corresponding request. 691 692 In JSON-RPC, responses include the 'id' field matching the request: 693 {v 694 { 695 "jsonrpc": "2.0", 696 "id": 1, 697 "result": { 698 "contents": [ 699 { 700 "uri": "file:///project/src/main.rs", 701 "mimeType": "text/x-rust", 702 "text": "fn main() {\n println!(\"Hello world!\");\n}" 703 } 704 ] 705 } 706 } 707 v} *) 708 709 type error = { 710 id : RequestId.t; 711 (** ID matching the original request, allowing clients to correlate 712 errors with their originating requests. *) 713 code : int; 714 (** Error code indicating the type of error, following the JSON-RPC 715 standard. Common codes include: 716 - -32700: Parse error 717 - -32600: Invalid request 718 - -32601: Method not found 719 - -32602: Invalid params 720 - -32603: Internal error 721 - -32002: Resource not found (MCP-specific) 722 - -32001: Authentication required (MCP-specific) *) 723 message : string; 724 (** Human-readable error message describing the issue. This should be 725 concise but informative enough for debugging. *) 726 data : Json.t option; 727 (** Optional additional error data as arbitrary JSON. This can provide 728 more context about the error, such as which resource wasn't found or 729 which parameter was invalid. *) 730 } 731 (** Error represents an error response to a JSON-RPC request. 732 733 Errors are sent in reply to requests when processing fails. Each error 734 must include the same ID as its corresponding request. 735 736 MCP defines several standard error codes: 737 - Standard JSON-RPC errors (-32700 to -32603) 738 - MCP-specific errors (-32002 for resource not found, etc.) 739 740 In JSON-RPC, errors follow this structure: 741 {v 742 { 743 "jsonrpc": "2.0", 744 "id": 1, 745 "error": { 746 "code": -32002, 747 "message": "Resource not found", 748 "data": { 749 "uri": "file:///nonexistent.txt" 750 } 751 } 752 } 753 v} *) 754 755 (** Union type for all JSON-RPC message kinds, providing a single type that 756 can represent any MCP message. *) 757 type t = 758 | Notification of notification 759 | Request of request 760 | Response of response 761 | Error of error 762 763 val yojson_of_notification : notification -> Json.t 764 (** Convert notification to Yojson representation 765 @param notification The notification to convert 766 @return JSON representation of the notification *) 767 768 val yojson_of_request : request -> Json.t 769 (** Convert request to Yojson representation 770 @param request The request to convert 771 @return JSON representation of the request *) 772 773 val yojson_of_response : response -> Json.t 774 (** Convert response to Yojson representation 775 @param response The response to convert 776 @return JSON representation of the response *) 777 778 val yojson_of_error : error -> Json.t 779 (** Convert error to Yojson representation 780 @param error The error to convert 781 @return JSON representation of the error *) 782 783 val yojson_of_t : t -> Json.t 784 (** Convert any message to Yojson representation 785 @param message The message to convert 786 @return JSON representation of the message *) 787 788 val notification_of_yojson : Json.t -> notification 789 (** Convert Yojson representation to notification 790 @param json JSON representation of a notification 791 @return Parsed notification object 792 @raise Parse error if the JSON is not a valid notification *) 793 794 val request_of_yojson : Json.t -> request 795 (** Convert Yojson representation to request 796 @param json JSON representation of a request 797 @return Parsed request object 798 @raise Parse error if the JSON is not a valid request *) 799 800 val response_of_yojson : Json.t -> response 801 (** Convert Yojson representation to response 802 @param json JSON representation of a response 803 @return Parsed response object 804 @raise Parse error if the JSON is not a valid response *) 805 806 val error_of_yojson : Json.t -> error 807 (** Convert Yojson representation to error 808 @param json JSON representation of an error 809 @return Parsed error object 810 @raise Parse error if the JSON is not a valid error *) 811 812 val t_of_yojson : Json.t -> t 813 (** Convert Yojson representation to any message 814 @param json JSON representation of any message type 815 @return Parsed message object 816 @raise Parse error if the JSON is not a valid message *) 817 818 val create_notification : ?params:Json.t option -> meth:Method.t -> unit -> t 819 (** Create a new notification message 820 @param params Optional parameters for the notification 821 @param meth Method name for the notification 822 @return A new JSON-RPC notification message *) 823 824 val create_request : 825 ?params:Json.t option -> 826 ?progress_token:ProgressToken.t option -> 827 id:RequestId.t -> 828 meth:Method.t -> 829 unit -> 830 t 831 (** Create a new request message 832 @param params Optional parameters for the request 833 @param progress_token Optional progress token for long-running operations 834 @param id Unique identifier for the request 835 @param meth Method name for the request 836 @return A new JSON-RPC request message *) 837 838 val create_response : id:RequestId.t -> result:Json.t -> t 839 (** Create a new response message 840 @param id ID matching the original request 841 @param result Result of the successful request 842 @return A new JSON-RPC response message *) 843 844 val create_error : 845 id:RequestId.t -> 846 code:int -> 847 message:string -> 848 ?data:Json.t option -> 849 unit -> 850 t 851 (** Create a new error message 852 @param id ID matching the original request 853 @param code Error code indicating the type of error 854 @param message Human-readable error message 855 @param data Optional additional error data 856 @return A new JSON-RPC error message *) 857end 858 859(** Initialize request/response - The first phase of the MCP lifecycle 860 861 The initialization phase is the mandatory first interaction between client 862 and server. During this phase, the protocol version is negotiated and 863 capabilities are exchanged to determine which optional features will be 864 available during the session. 865 866 This follows a strict sequence: 1. Client sends an InitializeRequest 867 containing its capabilities and protocol version 2. Server responds with an 868 InitializeResult containing its capabilities and protocol version 3. Client 869 sends an InitializedNotification to signal it's ready for normal operations 870 871 The Initialize module handles steps 1 and 2 of this process. *) 872module Initialize : sig 873 (** Initialize request *) 874 module Request : sig 875 type t = { 876 capabilities : Json.t; 877 (** ClientCapabilities that define supported optional features. This 878 includes which optional protocol features the client supports, 879 such as 'roots' (filesystem access), 'sampling' (LLM generation), 880 and any experimental features. *) 881 client_info : Implementation.t; 882 (** Client implementation details (name and version) used for 883 identification and debugging. Helps servers understand which 884 client they're working with. *) 885 protocol_version : string; 886 (** MCP protocol version supported by the client, formatted as 887 YYYY-MM-DD according to the MCP versioning scheme. Example: 888 "2025-03-26" *) 889 } 890 (** InitializeRequest starts the MCP lifecycle, negotiating capabilities and 891 protocol versions between client and server. This is always the first 892 message sent by the client and MUST NOT be part of a JSON-RPC batch. 893 894 The client SHOULD send the latest protocol version it supports. If the 895 server does not support this version, it will respond with a version it 896 does support, and the client must either use that version or disconnect. 897 *) 898 899 include Json.Jsonable.S with type t := t 900 901 val create : 902 capabilities:Json.t -> 903 client_info:Implementation.t -> 904 protocol_version:string -> 905 t 906 (** Create a new initialization request 907 @param capabilities 908 Client capabilities that define supported optional features 909 @param client_info Client implementation details 910 @param protocol_version MCP protocol version supported by the client 911 @return A new initialization request *) 912 913 val to_jsonrpc : id:RequestId.t -> t -> JSONRPCMessage.t 914 (** Convert to JSON-RPC message 915 @param id Unique request identifier 916 @param t Initialization request 917 @return JSON-RPC message containing the initialization request *) 918 end 919 920 (** Initialize result *) 921 module Result : sig 922 type t = { 923 capabilities : Json.t; 924 (** ServerCapabilities that define supported optional features. This 925 declares which server features are available, including: 926 - prompts: Server provides prompt templates 927 - resources: Server provides readable resources 928 - tools: Server exposes callable tools 929 - logging: Server emits structured log messages 930 931 Each capability may have sub-capabilities like: 932 - listChanged: Server will notify when available items change 933 - subscribe: Clients can subscribe to individual resources *) 934 server_info : Implementation.t; 935 (** Server implementation details (name and version) used for 936 identification and debugging. Helps clients understand which 937 server they're working with. *) 938 protocol_version : string; 939 (** MCP protocol version supported by the server, formatted as 940 YYYY-MM-DD. If the server supports the client's requested version, 941 it responds with the same version. Otherwise, it responds with a 942 version it does support. *) 943 instructions : string option; 944 (** Optional instructions for using the server. These can provide 945 human-readable guidance on how to interact with this specific 946 server implementation. *) 947 meta : Json.t option; 948 (** Optional additional metadata as arbitrary JSON. Can contain 949 server-specific information not covered by the standard fields. *) 950 } 951 (** InitializeResult is the server's response to an initialization request, 952 completing capability negotiation and establishing the protocol version. 953 954 After receiving this message, the client must send an 955 InitializedNotification. The server should not send any requests other 956 than pings and logging before receiving the initialized notification. *) 957 958 include Json.Jsonable.S with type t := t 959 960 val create : 961 capabilities:Json.t -> 962 server_info:Implementation.t -> 963 protocol_version:string -> 964 ?instructions:string -> 965 ?meta:Json.t -> 966 unit -> 967 t 968 (** Create a new initialization result 969 @param capabilities 970 Server capabilities that define supported optional features 971 @param server_info Server implementation details 972 @param protocol_version MCP protocol version supported by the server 973 @param instructions Optional instructions for using the server 974 @param meta Optional additional metadata 975 @return A new initialization result *) 976 977 val to_jsonrpc : id:RequestId.t -> t -> JSONRPCMessage.t 978 (** Convert to JSON-RPC message 979 @param id ID matching the original request 980 @param t Initialization result 981 @return JSON-RPC message containing the initialization result *) 982 end 983end 984 985(** Initialized notification - Completes the initialization phase of the MCP 986 lifecycle *) 987module Initialized : sig 988 module Notification : sig 989 type t = { 990 meta : Json.t option; 991 (** Optional additional metadata as arbitrary JSON. Can contain 992 client-specific information not covered by the standard fields. *) 993 } 994 (** InitializedNotification is sent by the client after receiving the 995 initialization response, indicating it's ready to begin normal 996 operations. This completes the three-step initialization process, after 997 which both client and server can freely exchange messages according to 998 the negotiated capabilities. 999 1000 Only after this notification has been sent should the client begin 1001 normal operations like listing resources, calling tools, or requesting 1002 prompts. *) 1003 1004 include Json.Jsonable.S with type t := t 1005 1006 val create : ?meta:Json.t -> unit -> t 1007 (** Create a new initialized notification 1008 @param meta Optional additional metadata 1009 @return A new initialized notification *) 1010 1011 val to_jsonrpc : t -> JSONRPCMessage.t 1012 (** Convert to JSON-RPC message 1013 @param t Initialized notification 1014 @return JSON-RPC message containing the initialized notification *) 1015 end 1016end 1017 1018val parse_message : Json.t -> JSONRPCMessage.t 1019(** Parse a JSON message into an MCP message 1020 1021 This function takes a raw JSON value and parses it into a structured MCP 1022 message. It's the primary entry point for processing incoming JSON-RPC 1023 messages in the MCP protocol. 1024 1025 The function determines the message type (notification, request, response, 1026 or error) based on the presence and values of specific fields: 1027 - A message with "method" but no "id" is a notification 1028 - A message with "method" and "id" is a request 1029 - A message with "id" and "result" is a response 1030 - A message with "id" and "error" is an error 1031 1032 @param json 1033 The JSON message to parse, typically received from the transport layer 1034 @return The parsed MCP message as a structured JSONRPCMessage.t value 1035 @raise Parse error if the JSON cannot be parsed as a valid MCP message *) 1036 1037val create_notification : 1038 ?params:Json.t option -> meth:Method.t -> unit -> JSONRPCMessage.t 1039(** Create a new notification message 1040 1041 Notifications are one-way messages that don't expect a response. This is a 1042 convenience wrapper around JSONRPCMessage.create_notification. 1043 1044 Common notifications in MCP include: 1045 - "notifications/initialized" - Sent after initialization 1046 - "notifications/progress" - Updates on long-running operations 1047 - "notifications/resources/updated" - Resource content changed 1048 - "notifications/prompts/list_changed" - Available prompts changed 1049 - "notifications/tools/list_changed" - Available tools changed 1050 1051 @param params Optional parameters for the notification as a JSON value 1052 @param meth Method type for the notification 1053 @return A new JSON-RPC notification message *) 1054 1055val create_request : 1056 ?params:Json.t option -> 1057 ?progress_token:ProgressToken.t option -> 1058 id:RequestId.t -> 1059 meth:Method.t -> 1060 unit -> 1061 JSONRPCMessage.t 1062(** Create a new request message 1063 1064 Requests are messages that expect a corresponding response. This is a 1065 convenience wrapper around JSONRPCMessage.create_request. 1066 1067 Common requests in MCP include: 1068 - "initialize" - Start the MCP lifecycle 1069 - "resources/list" - Discover available resources 1070 - "resources/read" - Retrieve resource contents 1071 - "tools/list" - Discover available tools 1072 - "tools/call" - Invoke a tool 1073 - "prompts/list" - Discover available prompts 1074 - "prompts/get" - Retrieve a prompt template 1075 1076 @param params Optional parameters for the request as a JSON value 1077 @param progress_token 1078 Optional progress token for long-running operations that can report 1079 progress updates 1080 @param id 1081 Unique identifier for the request, used to correlate with the response 1082 @param meth Method type for the request 1083 @return A new JSON-RPC request message *) 1084 1085val create_response : id:RequestId.t -> result:Json.t -> JSONRPCMessage.t 1086(** Create a new response message 1087 1088 Responses are sent in reply to requests and contain successful results. This 1089 is a convenience wrapper around JSONRPCMessage.create_response. 1090 1091 Each response must include the same ID as its corresponding request to allow 1092 the client to correlate them, especially when multiple requests are in 1093 flight simultaneously. 1094 1095 @param id ID matching the original request 1096 @param result Result of the successful request as a JSON value 1097 @return A new JSON-RPC response message *) 1098 1099val create_error : 1100 id:RequestId.t -> 1101 code:int -> 1102 message:string -> 1103 ?data:Json.t option -> 1104 unit -> 1105 JSONRPCMessage.t 1106(** Create a new error message 1107 1108 Errors are sent in reply to requests when processing fails. This is a 1109 convenience wrapper around JSONRPCMessage.create_error. 1110 1111 MCP uses standard JSON-RPC error codes as well as some protocol-specific 1112 codes: 1113 - -32700: Parse error (invalid JSON) 1114 - -32600: Invalid request (malformed JSON-RPC) 1115 - -32601: Method not found 1116 - -32602: Invalid parameters 1117 - -32603: Internal error 1118 - -32002: Resource not found (MCP-specific) 1119 - -32001: Authentication required (MCP-specific) 1120 1121 @param id ID matching the original request 1122 @param code Error code indicating the type of error 1123 @param message Human-readable error message describing the issue 1124 @param data Optional additional error data providing more context 1125 @return A new JSON-RPC error message *) 1126 1127val make_text_content : string -> content 1128(** Create a new text content object 1129 @param text The text content 1130 @return A content value with the text *) 1131 1132val make_image_content : string -> string -> content 1133(** Create a new image content object 1134 @param data Base64-encoded image data 1135 @param mime_type MIME type of the image (e.g., "image/png", "image/jpeg") 1136 @return A content value with the image *) 1137 1138val make_audio_content : string -> string -> content 1139(** Create a new audio content object 1140 @param data Base64-encoded audio data 1141 @param mime_type MIME type of the audio (e.g., "audio/wav", "audio/mp3") 1142 @return A content value with the audio *) 1143 1144val make_resource_text_content : string -> string -> string option -> content 1145(** Create a new text resource content object 1146 @param uri URI that uniquely identifies the resource 1147 @param text The text content of the resource 1148 @param mime_type Optional MIME type of the text content 1149 @return A content value with the text resource *) 1150 1151val make_resource_blob_content : string -> string -> string option -> content 1152(** Create a new binary resource content object 1153 @param uri URI that uniquely identifies the resource 1154 @param blob Base64-encoded binary data 1155 @param mime_type Optional MIME type of the binary content 1156 @return A content value with the binary resource *)