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