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