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 - Algebraic data type representing all MCP methods *)
53module Method : sig
54 (** Method type representing all MCP protocol methods *)
55 type t =
56 (* Initialization and lifecycle methods *)
57 | Initialize (** Start the MCP lifecycle *)
58 | Initialized (** Signal readiness after initialization *)
59
60 (* Resource methods *)
61 | ResourcesList (** Discover available resources *)
62 | ResourcesRead (** Retrieve resource contents *)
63 | ResourcesTemplatesList (** List available resource templates *)
64 | ResourcesSubscribe (** Subscribe to resource changes *)
65 | ResourcesListChanged (** Resource list has changed *)
66 | ResourcesUpdated (** Resource has been updated *)
67
68 (* Tool methods *)
69 | ToolsList (** Discover available tools *)
70 | ToolsCall (** Invoke a tool *)
71 | ToolsListChanged (** Tool list has changed *)
72
73 (* Prompt methods *)
74 | PromptsList (** Discover available prompts *)
75 | PromptsGet (** Retrieve a prompt template with arguments *)
76 | PromptsListChanged (** Prompt list has changed *)
77
78 (* Progress notifications *)
79 | Progress (** Progress update for long-running operations *)
80
81 (** Convert method type to string representation
82 @param meth The method to convert
83 @return The string representation of the method (e.g., "initialize", "resources/list")
84 *)
85 val to_string : t -> string
86
87 (** Convert string to method type
88 @param s The string representation of the method
89 @return The corresponding method type
90 @raise Failure if the string is not a valid MCP method
91 *)
92 val of_string : string -> t
93end
94
95
96(** Common types *)
97
98(** Roles for conversation participants *)
99module Role : sig
100 (** Role represents conversation participants in MCP messages.
101 Roles can be either 'user' or 'assistant', determining the
102 source of each message in a conversation. *)
103 type t = [ `User | `Assistant ]
104 include Json.Jsonable.S with type t := t
105end
106
107(** Progress tokens for long-running operations *)
108module ProgressToken : sig
109 (** Progress tokens identify long-running operations and enable
110 servers to provide progress updates to clients. This is used
111 to track operations that may take significant time to complete. *)
112 type t = [ `String of string | `Int of int ]
113 include Json.Jsonable.S with type t := t
114end
115
116(** Request IDs *)
117module RequestId : sig
118 (** Request IDs uniquely identify JSON-RPC requests, allowing responses
119 to be correlated with their originating requests. They can be either
120 string or integer values. *)
121 type t = [ `String of string | `Int of int ]
122 include Json.Jsonable.S with type t := t
123end
124
125(** Cursors for pagination *)
126module Cursor : sig
127 (** Cursors enable pagination in list operations for resources, tools, and prompts.
128 When a server has more items than can be returned in a single response,
129 it provides a cursor for the client to retrieve subsequent pages. *)
130 type t = string
131 include Json.Jsonable.S with type t := t
132end
133
134(** Annotations for objects *)
135module Annotated : sig
136 (** Annotations provide metadata for content objects, allowing
137 role-specific targeting and priority settings. *)
138 type t = {
139 annotations: annotation option;
140 }
141 and annotation = {
142 audience: Role.t list option;
143 (** Optional list of roles that should receive this content *)
144 priority: float option;
145 (** Optional priority value for this content *)
146 }
147 include Json.Jsonable.S with type t := t
148end
149
150(** Text content - Core textual message representation in MCP *)
151module TextContent : sig
152 (** TextContent represents plain text messages in MCP conversations.
153 This is the most common content type used for natural language interactions
154 between users and assistants. Text content is used in prompts, tool results,
155 and model responses.
156
157 In JSON-RPC, this is represented as:
158 {v
159 {
160 "type": "text",
161 "text": "The text content of the message"
162 }
163 v}
164
165 For security, implementations must sanitize text content to prevent
166 injection attacks or unauthorized access to resources. *)
167 type t = {
168 text: string;
169 (** The actual text content as a UTF-8 encoded string *)
170 annotations: Annotated.annotation option;
171 (** Optional annotations for audience targeting and priority.
172 Annotations can restrict content visibility to specific roles (user/assistant)
173 and indicate relative importance of different content elements. *)
174 }
175 include Json.Jsonable.S with type t := t
176end
177
178(** Image content - Visual data representation in MCP *)
179module ImageContent : sig
180 (** ImageContent enables including visual information in MCP messages,
181 supporting multimodal interactions where visual context is important.
182
183 Images can be used in several scenarios:
184 - As user inputs for visual understanding tasks
185 - As context for generating descriptions or analysis
186 - As outputs from tools that generate visualizations
187 - As part of prompt templates with visual components
188
189 In JSON-RPC, this is represented as:
190 {v
191 {
192 "type": "image",
193 "data": "base64-encoded-image-data",
194 "mimeType": "image/png"
195 }
196 v}
197
198 The data MUST be base64-encoded to ensure safe transmission in JSON.
199 Common mime types include image/png, image/jpeg, image/gif, and image/svg+xml. *)
200 type t = {
201 data: string;
202 (** Base64-encoded image data. All binary image data must be encoded using
203 standard base64 encoding (RFC 4648) to safely transmit within JSON. *)
204 mime_type: string;
205 (** MIME type of the image (e.g., "image/png", "image/jpeg", "image/gif", "image/svg+xml").
206 This field is required and must accurately represent the image format to ensure
207 proper handling by clients. *)
208 annotations: Annotated.annotation option;
209 (** Optional annotations for audience targeting and priority.
210 Annotations can restrict content visibility to specific roles (user/assistant)
211 and indicate relative importance of different content elements. *)
212 }
213 include Json.Jsonable.S with type t := t
214end
215
216(** Audio content - Sound data representation in MCP *)
217module AudioContent : sig
218 (** AudioContent enables including audio information in MCP messages,
219 supporting multimodal interactions where audio context is important.
220
221 Audio can be used in several scenarios:
222 - As user inputs for speech recognition or audio analysis
223 - As context for transcription or sound classification tasks
224 - As outputs from tools that generate audio samples
225 - As part of prompt templates with audio components
226
227 In JSON-RPC, this is represented as:
228 {v
229 {
230 "type": "audio",
231 "data": "base64-encoded-audio-data",
232 "mimeType": "audio/wav"
233 }
234 v}
235
236 The data MUST be base64-encoded to ensure safe transmission in JSON.
237 Common mime types include audio/wav, audio/mp3, audio/ogg, and audio/mpeg. *)
238 type t = {
239 data: string;
240 (** Base64-encoded audio data. All binary audio data must be encoded using
241 standard base64 encoding (RFC 4648) to safely transmit within JSON. *)
242 mime_type: string;
243 (** MIME type of the audio (e.g., "audio/wav", "audio/mp3", "audio/ogg", "audio/mpeg").
244 This field is required and must accurately represent the audio format to ensure
245 proper handling by clients. *)
246 annotations: Annotated.annotation option;
247 (** Optional annotations for audience targeting and priority.
248 Annotations can restrict content visibility to specific roles (user/assistant)
249 and indicate relative importance of different content elements. *)
250 }
251 include Json.Jsonable.S with type t := t
252end
253
254(** Base resource contents - Core resource metadata in MCP *)
255module ResourceContents : sig
256 (** ResourceContents provides basic metadata for resources in MCP.
257
258 Resources are server-exposed data that provides context to language models,
259 such as files, database schemas, or application-specific information.
260 Each resource is uniquely identified by a URI.
261
262 The MCP resources architecture is designed to be application-driven, with
263 host applications determining how to incorporate context based on their needs.
264
265 In the protocol, resources are discovered via the 'resources/list' endpoint
266 and retrieved via the 'resources/read' endpoint. Servers that support resources
267 must declare the 'resources' capability during initialization. *)
268 type t = {
269 uri: string;
270 (** URI that uniquely identifies the resource.
271
272 Resources use standard URI schemes including:
273 - file:// - For filesystem-like resources
274 - https:// - For web-accessible resources
275 - git:// - For version control integration
276
277 The URI serves as a stable identifier even if the underlying content changes. *)
278 mime_type: string option;
279 (** Optional MIME type of the resource content to aid in client rendering.
280 Common MIME types include text/plain, application/json, image/png, etc.
281 For directories, the XDG MIME type inode/directory may be used. *)
282 }
283 include Json.Jsonable.S with type t := t
284end
285
286(** Text resource contents - Textual resource data *)
287module TextResourceContents : sig
288 (** TextResourceContents represents a text-based resource in MCP.
289
290 Text resources are used for sharing code snippets, documentation, logs,
291 configuration files, and other textual information with language models.
292
293 The server handles access control and security, ensuring that only
294 authorized resources are shared with clients.
295
296 In JSON-RPC, this is represented as:
297 {v
298 {
299 "uri": "file:///example.txt",
300 "mimeType": "text/plain",
301 "text": "Resource content"
302 }
303 v}
304 *)
305 type t = {
306 uri: string;
307 (** URI that uniquely identifies the resource.
308 This URI can be referenced in subsequent requests to fetch updates. *)
309 text: string;
310 (** The actual text content of the resource as a UTF-8 encoded string.
311 This may be sanitized by the server to remove sensitive information. *)
312 mime_type: string option;
313 (** Optional MIME type of the text content to aid in client rendering.
314 Common text MIME types include: text/plain, text/markdown, text/x-python,
315 application/json, text/html, text/csv, etc. *)
316 }
317 include Json.Jsonable.S with type t := t
318end
319
320(** Binary resource contents - Binary resource data *)
321module BlobResourceContents : sig
322 (** BlobResourceContents represents a binary resource in MCP.
323
324 Binary resources allow sharing non-textual data like images, audio files,
325 PDFs, and other binary formats with language models that support processing
326 such content.
327
328 In JSON-RPC, this is represented as:
329 {v
330 {
331 "uri": "file:///example.png",
332 "mimeType": "image/png",
333 "blob": "base64-encoded-data"
334 }
335 v}
336
337 Binary data MUST be properly base64-encoded to ensure safe transmission
338 in JSON payloads. *)
339 type t = {
340 uri: string;
341 (** URI that uniquely identifies the resource.
342 This URI can be referenced in subsequent requests to fetch updates. *)
343 blob: string;
344 (** Base64-encoded binary data using standard base64 encoding (RFC 4648).
345 This encoding ensures that binary data can be safely transmitted in JSON. *)
346 mime_type: string option;
347 (** Optional MIME type of the binary content to aid in client rendering.
348 Common binary MIME types include: image/png, image/jpeg, application/pdf,
349 audio/wav, video/mp4, application/octet-stream, etc. *)
350 }
351 include Json.Jsonable.S with type t := t
352end
353
354(** Embedded resource - Resource included directly in messages *)
355module EmbeddedResource : sig
356 (** EmbeddedResource allows referencing server-side resources directly
357 in MCP messages, enabling seamless incorporation of managed content.
358
359 Embedded resources can be included in:
360 - Tool results to provide rich context
361 - Prompt templates to include reference materials
362 - Messages to provide additional context to language models
363
364 In contrast to direct content (TextContent, ImageContent, AudioContent),
365 embedded resources have the advantage of being persistently stored on the server
366 with a stable URI, allowing later retrieval and updates through the resources API.
367
368 For example, a tool might return an embedded resource containing a chart or
369 a large dataset that the client can later reference or update. *)
370 type t = {
371 resource: [ `Text of TextResourceContents.t | `Blob of BlobResourceContents.t ];
372 (** The resource content, either as text or binary blob. *)
373 annotations: Annotated.annotation option;
374 (** Optional annotations for audience targeting and priority.
375 Annotations can restrict resource visibility to specific roles (user/assistant)
376 and indicate relative importance of different content elements. *)
377 }
378 include Json.Jsonable.S with type t := t
379end
380
381(** Content type used in messages - Unified multimodal content representation in MCP *)
382type content =
383 | Text of TextContent.t (** Text content for natural language messages. This is the most common content type for user-assistant interactions. *)
384 | Image of ImageContent.t (** Image content for visual data. Used for sharing visual context in multimodal conversations. *)
385 | Audio of AudioContent.t (** Audio content for audio data. Used for sharing audio context in multimodal conversations. *)
386 | Resource of EmbeddedResource.t (** Resource content for referencing server-side resources. Used for incorporating managed server content with stable URIs. *)
387
388(** Convert content to Yojson representation
389 @param content The content to convert
390 @return JSON representation of the content
391*)
392val yojson_of_content : content -> Json.t
393
394(** Convert Yojson representation to content
395 @param json JSON representation of content
396 @return Parsed content object
397*)
398val content_of_yojson : Json.t -> content
399
400(** Message for prompts - Template messages in the MCP prompts feature *)
401module PromptMessage : sig
402 (** PromptMessage represents a message in an MCP prompt template,
403 containing a role and content which can be customized with arguments.
404
405 Prompt messages are part of prompt templates exposed by servers through
406 the prompts/get endpoint. They define structured conversation templates
407 that can be instantiated with user-provided arguments.
408
409 The prompt feature is designed to be user-controlled, with prompts typically
410 exposed through UI elements like slash commands that users can explicitly select.
411
412 In JSON-RPC, prompt messages are represented as:
413 {v
414 {
415 "role": "user",
416 "content": {
417 "type": "text",
418 "text": "Please review this code: ${code}"
419 }
420 }
421 v}
422
423 Where $code would be replaced with a user-provided argument. *)
424 type t = {
425 role: Role.t;
426 (** The role of the message sender (user or assistant).
427 Prompt templates typically alternate between user and assistant messages
428 to create a conversation structure. *)
429 content: content;
430 (** The message content, which can be text, image, audio, or resource.
431 This unified content type supports rich multimodal prompts. *)
432 }
433 include Json.Jsonable.S with type t := t
434end
435
436(** Message for sampling - Messages used in LLM completion requests *)
437module SamplingMessage : sig
438 (** SamplingMessage represents a message in an MCP sampling request,
439 used for AI model generation based on a prompt.
440
441 The sampling feature allows clients to expose language model capabilities
442 to servers, enabling servers to request completions from the client's LLM.
443 This is effectively the reverse of the normal MCP flow, with the server
444 requesting generative capabilities from the client.
445
446 Sampling messages differ from prompt messages in that they don't support
447 embedded resources, as they represent the actual context window being
448 sent to the LLM rather than template definitions.
449
450 Clients that support sampling must declare the 'sampling' capability
451 during initialization. *)
452 type t = {
453 role: Role.t;
454 (** The role of the message sender (user or assistant).
455 Typically, a sampling request will contain multiple messages
456 representing a conversation history, with alternating roles. *)
457 content: [ `Text of TextContent.t | `Image of ImageContent.t | `Audio of AudioContent.t ];
458 (** The message content, restricted to text, image, or audio (no resources).
459 Resources are not included since sampling messages represent the
460 actual context window for the LLM, not template definitions. *)
461 }
462 include Json.Jsonable.S with type t := t
463end
464
465(** Implementation information *)
466module Implementation : sig
467 (** Implementation provides metadata about client and server implementations,
468 used during the initialization phase to identify each party. *)
469 type t = {
470 name: string;
471 (** Name of the implementation *)
472 version: string;
473 (** Version of the implementation *)
474 }
475 include Json.Jsonable.S with type t := t
476end
477
478(** JSONRPC message types - Core message protocol for MCP
479
480 MCP uses JSON-RPC 2.0 as its underlying messaging protocol.
481 All MCP messages are encoded as JSON-RPC 2.0 messages with UTF-8 encoding,
482 following the standard JSON-RPC message formats with some MCP-specific extensions.
483
484 MCP defines four message types:
485 1. Notifications: One-way messages that don't expect a response
486 2. Requests: Messages that expect a corresponding response
487 3. Responses: Replies to requests with successful results
488 4. Errors: Replies to requests with error information
489
490 These can be transported over multiple transport mechanisms:
491 - stdio: Communication over standard input/output
492 - Streamable HTTP: HTTP POST/GET with SSE for server streaming
493 - Custom transports: Implementation-specific transports
494
495 Messages may be sent individually or as part of a JSON-RPC batch.
496*)
497module JSONRPCMessage : sig
498 (** Notification represents a JSON-RPC notification (one-way message without a response).
499
500 Notifications are used for events that don't require a response, such as:
501 - The 'initialized' notification completing initialization
502 - Resource change notifications
503 - Progress updates for long-running operations
504 - List changed notifications for tools, resources, and prompts
505
506 In JSON-RPC, notifications are identified by the absence of an 'id' field:
507 {v
508 {
509 "jsonrpc": "2.0",
510 "method": "notifications/resources/updated",
511 "params": {
512 "uri": "file:///project/src/main.rs"
513 }
514 }
515 v}
516 *)
517 type notification = {
518 meth: Method.t;
519 (** Method for the notification, using the Method.t type to ensure type safety.
520 Examples: Method.Initialized, Method.ResourcesUpdated *)
521 params: Json.t option;
522 (** Optional parameters for the notification as arbitrary JSON.
523 The structure depends on the specific notification method. *)
524 }
525
526 (** Request represents a JSON-RPC request that expects a response.
527
528 Requests are used for operations that require a response, such as:
529 - Initialization
530 - Listing resources, tools, or prompts
531 - Reading resources
532 - Calling tools
533 - Getting prompts
534
535 In JSON-RPC, requests include an 'id' field that correlates with the response:
536 {v
537 {
538 "jsonrpc": "2.0",
539 "id": 1,
540 "method": "resources/read",
541 "params": {
542 "uri": "file:///project/src/main.rs"
543 }
544 }
545 v}
546 *)
547 type request = {
548 id: RequestId.t;
549 (** Unique identifier for the request, which will be echoed in the response.
550 This can be a string or integer and should be unique within the session. *)
551 meth: Method.t;
552 (** Method for the request, using the Method.t type to ensure type safety.
553 Examples: Method.Initialize, Method.ResourcesRead, Method.ToolsCall *)
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 meth Method name for the notification
718 @return A new JSON-RPC notification message
719 *)
720 val create_notification : ?params:Json.t option -> meth:Method.t -> 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 meth 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 -> meth:Method.t -> 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 meth Method type for the notification
918 @return A new JSON-RPC notification message
919*)
920val create_notification : ?params:Json.t option -> meth:Method.t -> 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 meth Method type for the request
941 @return A new JSON-RPC request message
942*)
943val create_request : ?params:Json.t option -> ?progress_token:ProgressToken.t option -> id:RequestId.t -> meth:Method.t -> 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