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