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