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