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