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 - Standard method names used in JSON-RPC messages *) 53module Method : sig 54 (** Standard protocol methods used in MCP JSON-RPC messages *) 55 56 val initialize : string (** "initialize" - Start the MCP lifecycle *) 57 58 val initialized : string (** "notifications/initialized" - Signal readiness after initialization *) 59 60 val resources_list : string (** "resources/list" - Discover available resources *) 61 62 val resources_read : string (** "resources/read" - Retrieve resource contents *) 63 64 val resources_templates_list : string (** "resources/templates/list" - List available resource templates *) 65 66 val resources_subscribe : string (** "resources/subscribe" - Subscribe to resource changes *) 67 68 val resources_list_changed : string (** "notifications/resources/list_changed" - Resource list has changed *) 69 70 val resources_updated : string (** "notifications/resources/updated" - Resource has been updated *) 71 72 val tools_list : string (** "tools/list" - Discover available tools *) 73 74 val tools_call : string (** "tools/call" - Invoke a tool *) 75 76 val tools_list_changed : string (** "notifications/tools/list_changed" - Tool list has changed *) 77 78 val prompts_list : string (** "prompts/list" - Discover available prompts *) 79 80 val prompts_get : string (** "prompts/get" - Retrieve a prompt template with arguments *) 81 82 val prompts_list_changed : string (** "notifications/prompts/list_changed" - Prompt list has changed *) 83 84 val progress : string (** "notifications/progress" - Progress update for long-running operations *) 85end 86 87 88(** Common types *) 89 90(** Roles for conversation participants *) 91module Role : sig 92 (** Role represents conversation participants in MCP messages. 93 Roles can be either 'user' or 'assistant', determining the 94 source of each message in a conversation. *) 95 type t = [ `User | `Assistant ] 96 include Json.Jsonable.S with type t := t 97end 98 99(** Progress tokens for long-running operations *) 100module ProgressToken : sig 101 (** Progress tokens identify long-running operations and enable 102 servers to provide progress updates to clients. This is used 103 to track operations that may take significant time to complete. *) 104 type t = [ `String of string | `Int of int ] 105 include Json.Jsonable.S with type t := t 106end 107 108(** Request IDs *) 109module RequestId : sig 110 (** Request IDs uniquely identify JSON-RPC requests, allowing responses 111 to be correlated with their originating requests. They can be either 112 string or integer values. *) 113 type t = [ `String of string | `Int of int ] 114 include Json.Jsonable.S with type t := t 115end 116 117(** Cursors for pagination *) 118module Cursor : sig 119 (** Cursors enable pagination in list operations for resources, tools, and prompts. 120 When a server has more items than can be returned in a single response, 121 it provides a cursor for the client to retrieve subsequent pages. *) 122 type t = string 123 include Json.Jsonable.S with type t := t 124end 125 126(** Annotations for objects *) 127module Annotated : sig 128 (** Annotations provide metadata for content objects, allowing 129 role-specific targeting and priority settings. *) 130 type t = { 131 annotations: annotation option; 132 } 133 and annotation = { 134 audience: Role.t list option; 135 (** Optional list of roles that should receive this content *) 136 priority: float option; 137 (** Optional priority value for this content *) 138 } 139 include Json.Jsonable.S with type t := t 140end 141 142(** Text content - Core textual message representation in MCP *) 143module TextContent : sig 144 (** TextContent represents plain text messages in MCP conversations. 145 This is the most common content type used for natural language interactions 146 between users and assistants. Text content is used in prompts, tool results, 147 and model responses. 148 149 In JSON-RPC, this is represented as: 150 {v 151 { 152 "type": "text", 153 "text": "The text content of the message" 154 } 155 v} 156 157 For security, implementations must sanitize text content to prevent 158 injection attacks or unauthorized access to resources. *) 159 type t = { 160 text: string; 161 (** The actual text content as a UTF-8 encoded string *) 162 annotations: Annotated.annotation option; 163 (** Optional annotations for audience targeting and priority. 164 Annotations can restrict content visibility to specific roles (user/assistant) 165 and indicate relative importance of different content elements. *) 166 } 167 include Json.Jsonable.S with type t := t 168end 169 170(** Image content - Visual data representation in MCP *) 171module ImageContent : sig 172 (** ImageContent enables including visual information in MCP messages, 173 supporting multimodal interactions where visual context is important. 174 175 Images can be used in several scenarios: 176 - As user inputs for visual understanding tasks 177 - As context for generating descriptions or analysis 178 - As outputs from tools that generate visualizations 179 - As part of prompt templates with visual components 180 181 In JSON-RPC, this is represented as: 182 {v 183 { 184 "type": "image", 185 "data": "base64-encoded-image-data", 186 "mimeType": "image/png" 187 } 188 v} 189 190 The data MUST be base64-encoded to ensure safe transmission in JSON. 191 Common mime types include image/png, image/jpeg, image/gif, and image/svg+xml. *) 192 type t = { 193 data: string; 194 (** Base64-encoded image data. All binary image data must be encoded using 195 standard base64 encoding (RFC 4648) to safely transmit within JSON. *) 196 mime_type: string; 197 (** MIME type of the image (e.g., "image/png", "image/jpeg", "image/gif", "image/svg+xml"). 198 This field is required and must accurately represent the image format to ensure 199 proper handling by clients. *) 200 annotations: Annotated.annotation option; 201 (** Optional annotations for audience targeting and priority. 202 Annotations can restrict content visibility to specific roles (user/assistant) 203 and indicate relative importance of different content elements. *) 204 } 205 include Json.Jsonable.S with type t := t 206end 207 208(** Audio content - Sound data representation in MCP *) 209module AudioContent : sig 210 (** AudioContent enables including audio information in MCP messages, 211 supporting multimodal interactions where audio context is important. 212 213 Audio can be used in several scenarios: 214 - As user inputs for speech recognition or audio analysis 215 - As context for transcription or sound classification tasks 216 - As outputs from tools that generate audio samples 217 - As part of prompt templates with audio components 218 219 In JSON-RPC, this is represented as: 220 {v 221 { 222 "type": "audio", 223 "data": "base64-encoded-audio-data", 224 "mimeType": "audio/wav" 225 } 226 v} 227 228 The data MUST be base64-encoded to ensure safe transmission in JSON. 229 Common mime types include audio/wav, audio/mp3, audio/ogg, and audio/mpeg. *) 230 type t = { 231 data: string; 232 (** Base64-encoded audio data. All binary audio data must be encoded using 233 standard base64 encoding (RFC 4648) to safely transmit within JSON. *) 234 mime_type: string; 235 (** MIME type of the audio (e.g., "audio/wav", "audio/mp3", "audio/ogg", "audio/mpeg"). 236 This field is required and must accurately represent the audio format to ensure 237 proper handling by clients. *) 238 annotations: Annotated.annotation option; 239 (** Optional annotations for audience targeting and priority. 240 Annotations can restrict content visibility to specific roles (user/assistant) 241 and indicate relative importance of different content elements. *) 242 } 243 include Json.Jsonable.S with type t := t 244end 245 246(** Base resource contents - Core resource metadata in MCP *) 247module ResourceContents : sig 248 (** ResourceContents provides basic metadata for resources in MCP. 249 250 Resources are server-exposed data that provides context to language models, 251 such as files, database schemas, or application-specific information. 252 Each resource is uniquely identified by a URI. 253 254 The MCP resources architecture is designed to be application-driven, with 255 host applications determining how to incorporate context based on their needs. 256 257 In the protocol, resources are discovered via the 'resources/list' endpoint 258 and retrieved via the 'resources/read' endpoint. Servers that support resources 259 must declare the 'resources' capability during initialization. *) 260 type t = { 261 uri: string; 262 (** URI that uniquely identifies the resource. 263 264 Resources use standard URI schemes including: 265 - file:// - For filesystem-like resources 266 - https:// - For web-accessible resources 267 - git:// - For version control integration 268 269 The URI serves as a stable identifier even if the underlying content changes. *) 270 mime_type: string option; 271 (** Optional MIME type of the resource content to aid in client rendering. 272 Common MIME types include text/plain, application/json, image/png, etc. 273 For directories, the XDG MIME type inode/directory may be used. *) 274 } 275 include Json.Jsonable.S with type t := t 276end 277 278(** Text resource contents - Textual resource data *) 279module TextResourceContents : sig 280 (** TextResourceContents represents a text-based resource in MCP. 281 282 Text resources are used for sharing code snippets, documentation, logs, 283 configuration files, and other textual information with language models. 284 285 The server handles access control and security, ensuring that only 286 authorized resources are shared with clients. 287 288 In JSON-RPC, this is represented as: 289 {v 290 { 291 "uri": "file:///example.txt", 292 "mimeType": "text/plain", 293 "text": "Resource content" 294 } 295 v} 296 *) 297 type t = { 298 uri: string; 299 (** URI that uniquely identifies the resource. 300 This URI can be referenced in subsequent requests to fetch updates. *) 301 text: string; 302 (** The actual text content of the resource as a UTF-8 encoded string. 303 This may be sanitized by the server to remove sensitive information. *) 304 mime_type: string option; 305 (** Optional MIME type of the text content to aid in client rendering. 306 Common text MIME types include: text/plain, text/markdown, text/x-python, 307 application/json, text/html, text/csv, etc. *) 308 } 309 include Json.Jsonable.S with type t := t 310end 311 312(** Binary resource contents - Binary resource data *) 313module BlobResourceContents : sig 314 (** BlobResourceContents represents a binary resource in MCP. 315 316 Binary resources allow sharing non-textual data like images, audio files, 317 PDFs, and other binary formats with language models that support processing 318 such content. 319 320 In JSON-RPC, this is represented as: 321 {v 322 { 323 "uri": "file:///example.png", 324 "mimeType": "image/png", 325 "blob": "base64-encoded-data" 326 } 327 v} 328 329 Binary data MUST be properly base64-encoded to ensure safe transmission 330 in JSON payloads. *) 331 type t = { 332 uri: string; 333 (** URI that uniquely identifies the resource. 334 This URI can be referenced in subsequent requests to fetch updates. *) 335 blob: string; 336 (** Base64-encoded binary data using standard base64 encoding (RFC 4648). 337 This encoding ensures that binary data can be safely transmitted in JSON. *) 338 mime_type: string option; 339 (** Optional MIME type of the binary content to aid in client rendering. 340 Common binary MIME types include: image/png, image/jpeg, application/pdf, 341 audio/wav, video/mp4, application/octet-stream, etc. *) 342 } 343 include Json.Jsonable.S with type t := t 344end 345 346(** Embedded resource - Resource included directly in messages *) 347module EmbeddedResource : sig 348 (** EmbeddedResource allows referencing server-side resources directly 349 in MCP messages, enabling seamless incorporation of managed content. 350 351 Embedded resources can be included in: 352 - Tool results to provide rich context 353 - Prompt templates to include reference materials 354 - Messages to provide additional context to language models 355 356 In contrast to direct content (TextContent, ImageContent, AudioContent), 357 embedded resources have the advantage of being persistently stored on the server 358 with a stable URI, allowing later retrieval and updates through the resources API. 359 360 For example, a tool might return an embedded resource containing a chart or 361 a large dataset that the client can later reference or update. *) 362 type t = { 363 resource: [ `Text of TextResourceContents.t | `Blob of BlobResourceContents.t ]; 364 (** The resource content, either as text or binary blob. *) 365 annotations: Annotated.annotation option; 366 (** Optional annotations for audience targeting and priority. 367 Annotations can restrict resource visibility to specific roles (user/assistant) 368 and indicate relative importance of different content elements. *) 369 } 370 include Json.Jsonable.S with type t := t 371end 372 373(** Content type used in messages - Unified multimodal content representation in MCP *) 374type content = 375 | Text of TextContent.t (** Text content for natural language messages. This is the most common content type for user-assistant interactions. *) 376 | Image of ImageContent.t (** Image content for visual data. Used for sharing visual context in multimodal conversations. *) 377 | Audio of AudioContent.t (** Audio content for audio data. Used for sharing audio context in multimodal conversations. *) 378 | Resource of EmbeddedResource.t (** Resource content for referencing server-side resources. Used for incorporating managed server content with stable URIs. *) 379 380(** Convert content to Yojson representation 381 @param content The content to convert 382 @return JSON representation of the content 383*) 384val yojson_of_content : content -> Json.t 385 386(** Convert Yojson representation to content 387 @param json JSON representation of content 388 @return Parsed content object 389*) 390val content_of_yojson : Json.t -> content 391 392(** Message for prompts - Template messages in the MCP prompts feature *) 393module PromptMessage : sig 394 (** PromptMessage represents a message in an MCP prompt template, 395 containing a role and content which can be customized with arguments. 396 397 Prompt messages are part of prompt templates exposed by servers through 398 the prompts/get endpoint. They define structured conversation templates 399 that can be instantiated with user-provided arguments. 400 401 The prompt feature is designed to be user-controlled, with prompts typically 402 exposed through UI elements like slash commands that users can explicitly select. 403 404 In JSON-RPC, prompt messages are represented as: 405 {v 406 { 407 "role": "user", 408 "content": { 409 "type": "text", 410 "text": "Please review this code: ${code}" 411 } 412 } 413 v} 414 415 Where $code would be replaced with a user-provided argument. *) 416 type t = { 417 role: Role.t; 418 (** The role of the message sender (user or assistant). 419 Prompt templates typically alternate between user and assistant messages 420 to create a conversation structure. *) 421 content: content; 422 (** The message content, which can be text, image, audio, or resource. 423 This unified content type supports rich multimodal prompts. *) 424 } 425 include Json.Jsonable.S with type t := t 426end 427 428(** Message for sampling - Messages used in LLM completion requests *) 429module SamplingMessage : sig 430 (** SamplingMessage represents a message in an MCP sampling request, 431 used for AI model generation based on a prompt. 432 433 The sampling feature allows clients to expose language model capabilities 434 to servers, enabling servers to request completions from the client's LLM. 435 This is effectively the reverse of the normal MCP flow, with the server 436 requesting generative capabilities from the client. 437 438 Sampling messages differ from prompt messages in that they don't support 439 embedded resources, as they represent the actual context window being 440 sent to the LLM rather than template definitions. 441 442 Clients that support sampling must declare the 'sampling' capability 443 during initialization. *) 444 type t = { 445 role: Role.t; 446 (** The role of the message sender (user or assistant). 447 Typically, a sampling request will contain multiple messages 448 representing a conversation history, with alternating roles. *) 449 content: [ `Text of TextContent.t | `Image of ImageContent.t | `Audio of AudioContent.t ]; 450 (** The message content, restricted to text, image, or audio (no resources). 451 Resources are not included since sampling messages represent the 452 actual context window for the LLM, not template definitions. *) 453 } 454 include Json.Jsonable.S with type t := t 455end 456 457(** Implementation information *) 458module Implementation : sig 459 (** Implementation provides metadata about client and server implementations, 460 used during the initialization phase to identify each party. *) 461 type t = { 462 name: string; 463 (** Name of the implementation *) 464 version: string; 465 (** Version of the implementation *) 466 } 467 include Json.Jsonable.S with type t := t 468end 469 470(** JSONRPC message types - Core message protocol for MCP 471 472 MCP uses JSON-RPC 2.0 as its underlying messaging protocol. 473 All MCP messages are encoded as JSON-RPC 2.0 messages with UTF-8 encoding, 474 following the standard JSON-RPC message formats with some MCP-specific extensions. 475 476 MCP defines four message types: 477 1. Notifications: One-way messages that don't expect a response 478 2. Requests: Messages that expect a corresponding response 479 3. Responses: Replies to requests with successful results 480 4. Errors: Replies to requests with error information 481 482 These can be transported over multiple transport mechanisms: 483 - stdio: Communication over standard input/output 484 - Streamable HTTP: HTTP POST/GET with SSE for server streaming 485 - Custom transports: Implementation-specific transports 486 487 Messages may be sent individually or as part of a JSON-RPC batch. 488*) 489module JSONRPCMessage : sig 490 (** Notification represents a JSON-RPC notification (one-way message without a response). 491 492 Notifications are used for events that don't require a response, such as: 493 - The 'initialized' notification completing initialization 494 - Resource change notifications 495 - Progress updates for long-running operations 496 - List changed notifications for tools, resources, and prompts 497 498 In JSON-RPC, notifications are identified by the absence of an 'id' field: 499 {v 500 { 501 "jsonrpc": "2.0", 502 "method": "notifications/resources/updated", 503 "params": { 504 "uri": "file:///project/src/main.rs" 505 } 506 } 507 v} 508 *) 509 type notification = { 510 method_: string; 511 (** Method name for the notification, following the MCP naming conventions. 512 Common method patterns include: 513 - "notifications/X" for standard notifications 514 - "notifications/X/Y" for more specific notifications 515 516 Examples: "notifications/initialized", "notifications/resources/updated" *) 517 params: Json.t option; 518 (** Optional parameters for the notification as arbitrary JSON. 519 The structure depends on the specific notification method. *) 520 } 521 522 (** Request represents a JSON-RPC request that expects a response. 523 524 Requests are used for operations that require a response, such as: 525 - Initialization 526 - Listing resources, tools, or prompts 527 - Reading resources 528 - Calling tools 529 - Getting prompts 530 531 In JSON-RPC, requests include an 'id' field that correlates with the response: 532 {v 533 { 534 "jsonrpc": "2.0", 535 "id": 1, 536 "method": "resources/read", 537 "params": { 538 "uri": "file:///project/src/main.rs" 539 } 540 } 541 v} 542 *) 543 type request = { 544 id: RequestId.t; 545 (** Unique identifier for the request, which will be echoed in the response. 546 This can be a string or integer and should be unique within the session. *) 547 method_: string; 548 (** Method name for the request, following the MCP naming conventions. 549 Common method patterns include: 550 - "X/Y" for standard operations 551 - "X/Y/Z" for more specific operations 552 553 Examples: "initialize", "resources/read", "tools/call", "prompts/get" *) 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 method_ Method name for the notification 718 @return A new JSON-RPC notification message 719 *) 720 val create_notification : ?params:Json.t option -> method_:string -> 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 method_ 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 -> method_:string -> 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 method_ Method name for the notification, typically following MCP naming conventions 918 @return A new JSON-RPC notification message 919*) 920val create_notification : ?params:Json.t option -> method_:string -> 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 method_ Method name for the request, following MCP naming conventions 941 @return A new JSON-RPC request message 942*) 943val create_request : ?params:Json.t option -> ?progress_token:ProgressToken.t option -> id:RequestId.t -> method_:string -> 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