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