···
1
-
(** MCP - Model Context Protocol implementation *)
1
+
(** MCP - Model Context Protocol implementation
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.
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
21
+
This implementation follows Protocol Revision 2025-03-26.
···
(** Roles for conversation participants *)
30
+
(** Role represents conversation participants in MCP messages.
31
+
Roles can be either 'user' or 'assistant', determining the
32
+
source of each message in a conversation. *)
type t = [ `User | `Assistant ]
include Json.Jsonable.S with type t := t
(** Progress tokens for long-running operations *)
module ProgressToken : sig
39
+
(** Progress tokens identify long-running operations and enable
40
+
servers to provide progress updates to clients. This is used
41
+
to track operations that may take significant time to complete. *)
type t = [ `String of string | `Int of int ]
include Json.Jsonable.S with type t := t
48
+
(** Request IDs uniquely identify JSON-RPC requests, allowing responses
49
+
to be correlated with their originating requests. They can be either
50
+
string or integer values. *)
type t = [ `String of string | `Int of int ]
include Json.Jsonable.S with type t := t
(** Cursors for pagination *)
57
+
(** Cursors enable pagination in list operations for resources, tools, and prompts.
58
+
When a server has more items than can be returned in a single response,
59
+
it provides a cursor for the client to retrieve subsequent pages. *)
include Json.Jsonable.S with type t := t
(** Annotations for objects *)
66
+
(** Annotations provide metadata for content objects, allowing
67
+
role-specific targeting and priority settings. *)
annotations: annotation option;
audience: Role.t list option;
73
+
(** Optional list of roles that should receive this content *)
75
+
(** Optional priority value for this content *)
include Json.Jsonable.S with type t := t
80
+
(** Text content - Core textual message representation in MCP *)
82
+
(** TextContent represents plain text messages in MCP conversations.
83
+
This is the most common content type used for natural language interactions
84
+
between users and assistants. Text content is used in prompts, tool results,
85
+
and model responses.
87
+
In JSON-RPC, this is represented as:
91
+
"text": "The text content of the message"
95
+
For security, implementations must sanitize text content to prevent
96
+
injection attacks or unauthorized access to resources. *)
99
+
(** The actual text content as a UTF-8 encoded string *)
annotations: Annotated.annotation option;
101
+
(** Optional annotations for audience targeting and priority.
102
+
Annotations can restrict content visibility to specific roles (user/assistant)
103
+
and indicate relative importance of different content elements. *)
include Json.Jsonable.S with type t := t
52
-
(** Image content *)
108
+
(** Image content - Visual data representation in MCP *)
module ImageContent : sig
110
+
(** ImageContent enables including visual information in MCP messages,
111
+
supporting multimodal interactions where visual context is important.
113
+
Images can be used in several scenarios:
114
+
- As user inputs for visual understanding tasks
115
+
- As context for generating descriptions or analysis
116
+
- As outputs from tools that generate visualizations
117
+
- As part of prompt templates with visual components
119
+
In JSON-RPC, this is represented as:
123
+
"data": "base64-encoded-image-data",
124
+
"mimeType": "image/png"
128
+
The data MUST be base64-encoded to ensure safe transmission in JSON.
129
+
Common mime types include image/png, image/jpeg, image/gif, and image/svg+xml. *)
132
+
(** Base64-encoded image data. All binary image data must be encoded using
133
+
standard base64 encoding (RFC 4648) to safely transmit within JSON. *)
135
+
(** MIME type of the image (e.g., "image/png", "image/jpeg", "image/gif", "image/svg+xml").
136
+
This field is required and must accurately represent the image format to ensure
137
+
proper handling by clients. *)
annotations: Annotated.annotation option;
139
+
(** Optional annotations for audience targeting and priority.
140
+
Annotations can restrict content visibility to specific roles (user/assistant)
141
+
and indicate relative importance of different content elements. *)
include Json.Jsonable.S with type t := t
62
-
(** Audio content *)
146
+
(** Audio content - Sound data representation in MCP *)
module AudioContent : sig
148
+
(** AudioContent enables including audio information in MCP messages,
149
+
supporting multimodal interactions where audio context is important.
151
+
Audio can be used in several scenarios:
152
+
- As user inputs for speech recognition or audio analysis
153
+
- As context for transcription or sound classification tasks
154
+
- As outputs from tools that generate audio samples
155
+
- As part of prompt templates with audio components
157
+
In JSON-RPC, this is represented as:
161
+
"data": "base64-encoded-audio-data",
162
+
"mimeType": "audio/wav"
166
+
The data MUST be base64-encoded to ensure safe transmission in JSON.
167
+
Common mime types include audio/wav, audio/mp3, audio/ogg, and audio/mpeg. *)
170
+
(** Base64-encoded audio data. All binary audio data must be encoded using
171
+
standard base64 encoding (RFC 4648) to safely transmit within JSON. *)
173
+
(** MIME type of the audio (e.g., "audio/wav", "audio/mp3", "audio/ogg", "audio/mpeg").
174
+
This field is required and must accurately represent the audio format to ensure
175
+
proper handling by clients. *)
annotations: Annotated.annotation option;
177
+
(** Optional annotations for audience targeting and priority.
178
+
Annotations can restrict content visibility to specific roles (user/assistant)
179
+
and indicate relative importance of different content elements. *)
include Json.Jsonable.S with type t := t
72
-
(** Base resource contents *)
184
+
(** Base resource contents - Core resource metadata in MCP *)
module ResourceContents : sig
186
+
(** ResourceContents provides basic metadata for resources in MCP.
188
+
Resources are server-exposed data that provides context to language models,
189
+
such as files, database schemas, or application-specific information.
190
+
Each resource is uniquely identified by a URI.
192
+
The MCP resources architecture is designed to be application-driven, with
193
+
host applications determining how to incorporate context based on their needs.
195
+
In the protocol, resources are discovered via the 'resources/list' endpoint
196
+
and retrieved via the 'resources/read' endpoint. Servers that support resources
197
+
must declare the 'resources' capability during initialization. *)
200
+
(** URI that uniquely identifies the resource.
202
+
Resources use standard URI schemes including:
203
+
- file:// - For filesystem-like resources
204
+
- https:// - For web-accessible resources
205
+
- git:// - For version control integration
207
+
The URI serves as a stable identifier even if the underlying content changes. *)
mime_type: string option;
209
+
(** Optional MIME type of the resource content to aid in client rendering.
210
+
Common MIME types include text/plain, application/json, image/png, etc.
211
+
For directories, the XDG MIME type inode/directory may be used. *)
include Json.Jsonable.S with type t := t
81
-
(** Text resource contents *)
216
+
(** Text resource contents - Textual resource data *)
module TextResourceContents : sig
218
+
(** TextResourceContents represents a text-based resource in MCP.
220
+
Text resources are used for sharing code snippets, documentation, logs,
221
+
configuration files, and other textual information with language models.
223
+
The server handles access control and security, ensuring that only
224
+
authorized resources are shared with clients.
226
+
In JSON-RPC, this is represented as:
229
+
"uri": "file:///example.txt",
230
+
"mimeType": "text/plain",
231
+
"text": "Resource content"
237
+
(** URI that uniquely identifies the resource.
238
+
This URI can be referenced in subsequent requests to fetch updates. *)
240
+
(** The actual text content of the resource as a UTF-8 encoded string.
241
+
This may be sanitized by the server to remove sensitive information. *)
mime_type: string option;
243
+
(** Optional MIME type of the text content to aid in client rendering.
244
+
Common text MIME types include: text/plain, text/markdown, text/x-python,
245
+
application/json, text/html, text/csv, etc. *)
include Json.Jsonable.S with type t := t
91
-
(** Binary resource contents *)
250
+
(** Binary resource contents - Binary resource data *)
module BlobResourceContents : sig
252
+
(** BlobResourceContents represents a binary resource in MCP.
254
+
Binary resources allow sharing non-textual data like images, audio files,
255
+
PDFs, and other binary formats with language models that support processing
258
+
In JSON-RPC, this is represented as:
261
+
"uri": "file:///example.png",
262
+
"mimeType": "image/png",
263
+
"blob": "base64-encoded-data"
267
+
Binary data MUST be properly base64-encoded to ensure safe transmission
268
+
in JSON payloads. *)
271
+
(** URI that uniquely identifies the resource.
272
+
This URI can be referenced in subsequent requests to fetch updates. *)
274
+
(** Base64-encoded binary data using standard base64 encoding (RFC 4648).
275
+
This encoding ensures that binary data can be safely transmitted in JSON. *)
mime_type: string option;
277
+
(** Optional MIME type of the binary content to aid in client rendering.
278
+
Common binary MIME types include: image/png, image/jpeg, application/pdf,
279
+
audio/wav, video/mp4, application/octet-stream, etc. *)
include Json.Jsonable.S with type t := t
101
-
(** Embedded resource *)
284
+
(** Embedded resource - Resource included directly in messages *)
module EmbeddedResource : sig
286
+
(** EmbeddedResource allows referencing server-side resources directly
287
+
in MCP messages, enabling seamless incorporation of managed content.
289
+
Embedded resources can be included in:
290
+
- Tool results to provide rich context
291
+
- Prompt templates to include reference materials
292
+
- Messages to provide additional context to language models
294
+
In contrast to direct content (TextContent, ImageContent, AudioContent),
295
+
embedded resources have the advantage of being persistently stored on the server
296
+
with a stable URI, allowing later retrieval and updates through the resources API.
298
+
For example, a tool might return an embedded resource containing a chart or
299
+
a large dataset that the client can later reference or update. *)
resource: [ `Text of TextResourceContents.t | `Blob of BlobResourceContents.t ];
302
+
(** The resource content, either as text or binary blob.
303
+
This polymorphic variant allows handling both text and binary resources
304
+
with a unified interface, while maintaining type safety. *)
annotations: Annotated.annotation option;
306
+
(** Optional annotations for audience targeting and priority.
307
+
Annotations can restrict resource visibility to specific roles (user/assistant)
308
+
and indicate relative importance of different content elements. *)
include Json.Jsonable.S with type t := t
110
-
(** Content type used in messages *)
313
+
(** Content type used in messages - Unified multimodal content representation in MCP *)
112
-
| Text of TextContent.t
113
-
| Image of ImageContent.t
114
-
| Audio of AudioContent.t
115
-
| Resource of EmbeddedResource.t
315
+
| Text of TextContent.t (** Text content for natural language messages. This is the most common content type for user-assistant interactions. *)
316
+
| Image of ImageContent.t (** Image content for visual data. Used for sharing visual context in multimodal conversations. *)
317
+
| Audio of AudioContent.t (** Audio content for audio data. Used for sharing audio context in multimodal conversations. *)
318
+
| Resource of EmbeddedResource.t (** Resource content for referencing server-side resources. Used for incorporating managed server content with stable URIs. *)
320
+
(** Convert content to Yojson representation
321
+
@param content The content to convert
322
+
@return JSON representation of the content
val yojson_of_content : content -> Json.t
326
+
(** Convert Yojson representation to content
327
+
@param json JSON representation of content
328
+
@return Parsed content object
val content_of_yojson : Json.t -> content
120
-
(** Message for prompts *)
332
+
(** Message for prompts - Template messages in the MCP prompts feature *)
module PromptMessage : sig
334
+
(** PromptMessage represents a message in an MCP prompt template,
335
+
containing a role and content which can be customized with arguments.
337
+
Prompt messages are part of prompt templates exposed by servers through
338
+
the prompts/get endpoint. They define structured conversation templates
339
+
that can be instantiated with user-provided arguments.
341
+
The prompt feature is designed to be user-controlled, with prompts typically
342
+
exposed through UI elements like slash commands that users can explicitly select.
344
+
In JSON-RPC, prompt messages are represented as:
350
+
"text": "Please review this code: ${code}"
355
+
Where $code would be replaced with a user-provided argument. *)
358
+
(** The role of the message sender (user or assistant).
359
+
Prompt templates typically alternate between user and assistant messages
360
+
to create a conversation structure. *)
362
+
(** The message content, which can be text, image, audio, or resource.
363
+
This unified content type supports rich multimodal prompts. *)
include Json.Jsonable.S with type t := t
129
-
(** Message for sampling *)
368
+
(** Message for sampling - Messages used in LLM completion requests *)
module SamplingMessage : sig
370
+
(** SamplingMessage represents a message in an MCP sampling request,
371
+
used for AI model generation based on a prompt.
373
+
The sampling feature allows clients to expose language model capabilities
374
+
to servers, enabling servers to request completions from the client's LLM.
375
+
This is effectively the reverse of the normal MCP flow, with the server
376
+
requesting generative capabilities from the client.
378
+
Sampling messages differ from prompt messages in that they don't support
379
+
embedded resources, as they represent the actual context window being
380
+
sent to the LLM rather than template definitions.
382
+
Clients that support sampling must declare the 'sampling' capability
383
+
during initialization. *)
386
+
(** The role of the message sender (user or assistant).
387
+
Typically, a sampling request will contain multiple messages
388
+
representing a conversation history, with alternating roles. *)
content: [ `Text of TextContent.t | `Image of ImageContent.t | `Audio of AudioContent.t ];
390
+
(** The message content, restricted to text, image, or audio (no resources).
391
+
Resources are not included since sampling messages represent the
392
+
actual context window for the LLM, not template definitions. *)
include Json.Jsonable.S with type t := t
(** Implementation information *)
module Implementation : sig
399
+
(** Implementation provides metadata about client and server implementations,
400
+
used during the initialization phase to identify each party. *)
403
+
(** Name of the implementation *)
405
+
(** Version of the implementation *)
include Json.Jsonable.S with type t := t
147
-
(** JSONRPC message types *)
410
+
(** JSONRPC message types - Core message protocol for MCP
412
+
MCP uses JSON-RPC 2.0 as its underlying messaging protocol.
413
+
All MCP messages are encoded as JSON-RPC 2.0 messages with UTF-8 encoding,
414
+
following the standard JSON-RPC message formats with some MCP-specific extensions.
416
+
MCP defines four message types:
417
+
1. Notifications: One-way messages that don't expect a response
418
+
2. Requests: Messages that expect a corresponding response
419
+
3. Responses: Replies to requests with successful results
420
+
4. Errors: Replies to requests with error information
422
+
These can be transported over multiple transport mechanisms:
423
+
- stdio: Communication over standard input/output
424
+
- Streamable HTTP: HTTP POST/GET with SSE for server streaming
425
+
- Custom transports: Implementation-specific transports
427
+
Messages may be sent individually or as part of a JSON-RPC batch.
module JSONRPCMessage : sig
430
+
(** Notification represents a JSON-RPC notification (one-way message without a response).
432
+
Notifications are used for events that don't require a response, such as:
433
+
- The 'initialized' notification completing initialization
434
+
- Resource change notifications
435
+
- Progress updates for long-running operations
436
+
- List changed notifications for tools, resources, and prompts
438
+
In JSON-RPC, notifications are identified by the absence of an 'id' field:
442
+
"method": "notifications/resources/updated",
444
+
"uri": "file:///project/src/main.rs"
451
+
(** Method name for the notification, following the MCP naming conventions.
452
+
Common method patterns include:
453
+
- "notifications/X" for standard notifications
454
+
- "notifications/X/Y" for more specific notifications
456
+
Examples: "notifications/initialized", "notifications/resources/updated" *)
458
+
(** Optional parameters for the notification as arbitrary JSON.
459
+
The structure depends on the specific notification method. *)
462
+
(** Request represents a JSON-RPC request that expects a response.
464
+
Requests are used for operations that require a response, such as:
466
+
- Listing resources, tools, or prompts
467
+
- Reading resources
471
+
In JSON-RPC, requests include an 'id' field that correlates with the response:
476
+
"method": "resources/read",
478
+
"uri": "file:///project/src/main.rs"
485
+
(** Unique identifier for the request, which will be echoed in the response.
486
+
This can be a string or integer and should be unique within the session. *)
488
+
(** Method name for the request, following the MCP naming conventions.
489
+
Common method patterns include:
490
+
- "X/Y" for standard operations
491
+
- "X/Y/Z" for more specific operations
493
+
Examples: "initialize", "resources/read", "tools/call", "prompts/get" *)
495
+
(** Optional parameters for the request as arbitrary JSON.
496
+
The structure depends on the specific request method. *)
progress_token: ProgressToken.t option;
498
+
(** Optional progress token for long-running operations.
499
+
If provided, the server can send progress notifications using this token
500
+
to inform the client about the operation's status. *)
503
+
(** Response represents a successful JSON-RPC response to a request.
505
+
Responses are sent in reply to requests and contain the successful result.
506
+
Each response must include the same ID as its corresponding request.
508
+
In JSON-RPC, responses include the 'id' field matching the request:
516
+
"uri": "file:///project/src/main.rs",
517
+
"mimeType": "text/x-rust",
518
+
"text": "fn main() {\n println!(\"Hello world!\");\n}"
527
+
(** ID matching the original request, allowing clients to correlate
528
+
responses with their originating requests, especially important
529
+
when multiple requests are in flight. *)
531
+
(** Result of the successful request as arbitrary JSON.
532
+
The structure depends on the specific request method that was called. *)
535
+
(** Error represents an error response to a JSON-RPC request.
537
+
Errors are sent in reply to requests when processing fails.
538
+
Each error must include the same ID as its corresponding request.
540
+
MCP defines several standard error codes:
541
+
- Standard JSON-RPC errors (-32700 to -32603)
542
+
- MCP-specific errors (-32002 for resource not found, etc.)
544
+
In JSON-RPC, errors follow this structure:
551
+
"message": "Resource not found",
553
+
"uri": "file:///nonexistent.txt"
561
+
(** ID matching the original request, allowing clients to correlate
562
+
errors with their originating requests. *)
564
+
(** Error code indicating the type of error, following the JSON-RPC standard.
565
+
Common codes include:
566
+
- -32700: Parse error
567
+
- -32600: Invalid request
568
+
- -32601: Method not found
569
+
- -32602: Invalid params
570
+
- -32603: Internal error
571
+
- -32002: Resource not found (MCP-specific)
572
+
- -32001: Authentication required (MCP-specific) *)
574
+
(** Human-readable error message describing the issue.
575
+
This should be concise but informative enough for debugging. *)
577
+
(** Optional additional error data as arbitrary JSON.
578
+
This can provide more context about the error, such as which
579
+
resource wasn't found or which parameter was invalid. *)
582
+
(** Union type for all JSON-RPC message kinds, providing a single type
583
+
that can represent any MCP message. *)
| Notification of notification
590
+
(** Convert notification to Yojson representation
591
+
@param notification The notification to convert
592
+
@return JSON representation of the notification
val yojson_of_notification : notification -> Json.t
596
+
(** Convert request to Yojson representation
597
+
@param request The request to convert
598
+
@return JSON representation of the request
val yojson_of_request : request -> Json.t
602
+
(** Convert response to Yojson representation
603
+
@param response The response to convert
604
+
@return JSON representation of the response
val yojson_of_response : response -> Json.t
608
+
(** Convert error to Yojson representation
609
+
@param error The error to convert
610
+
@return JSON representation of the error
val yojson_of_error : error -> Json.t
614
+
(** Convert any message to Yojson representation
615
+
@param message The message to convert
616
+
@return JSON representation of the message
val yojson_of_t : t -> Json.t
620
+
(** Convert Yojson representation to notification
621
+
@param json JSON representation of a notification
622
+
@return Parsed notification object
623
+
@raise Parse error if the JSON is not a valid notification
val notification_of_yojson : Json.t -> notification
627
+
(** Convert Yojson representation to request
628
+
@param json JSON representation of a request
629
+
@return Parsed request object
630
+
@raise Parse error if the JSON is not a valid request
val request_of_yojson : Json.t -> request
634
+
(** Convert Yojson representation to response
635
+
@param json JSON representation of a response
636
+
@return Parsed response object
637
+
@raise Parse error if the JSON is not a valid response
val response_of_yojson : Json.t -> response
641
+
(** Convert Yojson representation to error
642
+
@param json JSON representation of an error
643
+
@return Parsed error object
644
+
@raise Parse error if the JSON is not a valid error
val error_of_yojson : Json.t -> error
648
+
(** Convert Yojson representation to any message
649
+
@param json JSON representation of any message type
650
+
@return Parsed message object
651
+
@raise Parse error if the JSON is not a valid message
val t_of_yojson : Json.t -> t
655
+
(** Create a new notification message
656
+
@param params Optional parameters for the notification
657
+
@param method_ Method name for the notification
658
+
@return A new JSON-RPC notification message
val create_notification : ?params:Json.t option -> method_:string -> unit -> t
662
+
(** Create a new request message
663
+
@param params Optional parameters for the request
664
+
@param progress_token Optional progress token for long-running operations
665
+
@param id Unique identifier for the request
666
+
@param method_ Method name for the request
667
+
@return A new JSON-RPC request message
val create_request : ?params:Json.t option -> ?progress_token:ProgressToken.t option -> id:RequestId.t -> method_:string -> unit -> t
671
+
(** Create a new response message
672
+
@param id ID matching the original request
673
+
@param result Result of the successful request
674
+
@return A new JSON-RPC response message
val create_response : id:RequestId.t -> result:Json.t -> t
678
+
(** Create a new error message
679
+
@param id ID matching the original request
680
+
@param code Error code indicating the type of error
681
+
@param message Human-readable error message
682
+
@param data Optional additional error data
683
+
@return A new JSON-RPC error message
val create_error : id:RequestId.t -> code:int -> message:string -> ?data:Json.t option -> unit -> t
197
-
(** Initialize request/response *)
688
+
(** Initialize request/response - The first phase of the MCP lifecycle
690
+
The initialization phase is the mandatory first interaction between client and server.
691
+
During this phase, the protocol version is negotiated and capabilities are exchanged
692
+
to determine which optional features will be available during the session.
694
+
This follows a strict sequence:
695
+
1. Client sends an InitializeRequest containing its capabilities and protocol version
696
+
2. Server responds with an InitializeResult containing its capabilities and protocol version
697
+
3. Client sends an InitializedNotification to signal it's ready for normal operations
699
+
The Initialize module handles steps 1 and 2 of this process.
(** Initialize request *)
704
+
(** InitializeRequest starts the MCP lifecycle, negotiating capabilities
705
+
and protocol versions between client and server. This is always the first
706
+
message sent by the client and MUST NOT be part of a JSON-RPC batch.
708
+
The client SHOULD send the latest protocol version it supports. If the server
709
+
does not support this version, it will respond with a version it does support,
710
+
and the client must either use that version or disconnect. *)
202
-
capabilities: Json.t; (** ClientCapabilities *)
712
+
capabilities: Json.t; (** ClientCapabilities that define supported optional features.
713
+
This includes which optional protocol features the client supports,
714
+
such as 'roots' (filesystem access), 'sampling' (LLM generation),
715
+
and any experimental features. *)
client_info: Implementation.t;
717
+
(** Client implementation details (name and version) used for identification
718
+
and debugging. Helps servers understand which client they're working with. *)
protocol_version: string;
720
+
(** MCP protocol version supported by the client, formatted as YYYY-MM-DD
721
+
according to the MCP versioning scheme. Example: "2025-03-26" *)
include Json.Jsonable.S with type t := t
725
+
(** Create a new initialization request
726
+
@param capabilities Client capabilities that define supported optional features
727
+
@param client_info Client implementation details
728
+
@param protocol_version MCP protocol version supported by the client
729
+
@return A new initialization request
val create : capabilities:Json.t -> client_info:Implementation.t -> protocol_version:string -> t
733
+
(** Convert to JSON-RPC message
734
+
@param id Unique request identifier
735
+
@param t Initialization request
736
+
@return JSON-RPC message containing the initialization request
val to_jsonrpc : id:RequestId.t -> t -> JSONRPCMessage.t
743
+
(** InitializeResult is the server's response to an initialization request,
744
+
completing capability negotiation and establishing the protocol version.
746
+
After receiving this message, the client must send an InitializedNotification.
747
+
The server should not send any requests other than pings and logging before
748
+
receiving the initialized notification. *)
215
-
capabilities: Json.t; (** ServerCapabilities *)
750
+
capabilities: Json.t; (** ServerCapabilities that define supported optional features.
751
+
This declares which server features are available, including:
752
+
- prompts: Server provides prompt templates
753
+
- resources: Server provides readable resources
754
+
- tools: Server exposes callable tools
755
+
- logging: Server emits structured log messages
757
+
Each capability may have sub-capabilities like:
758
+
- listChanged: Server will notify when available items change
759
+
- subscribe: Clients can subscribe to individual resources *)
server_info: Implementation.t;
761
+
(** Server implementation details (name and version) used for identification
762
+
and debugging. Helps clients understand which server they're working with. *)
protocol_version: string;
764
+
(** MCP protocol version supported by the server, formatted as YYYY-MM-DD.
765
+
If the server supports the client's requested version, it responds with
766
+
the same version. Otherwise, it responds with a version it does support. *)
instructions: string option;
768
+
(** Optional instructions for using the server. These can provide human-readable
769
+
guidance on how to interact with this specific server implementation. *)
771
+
(** Optional additional metadata as arbitrary JSON. Can contain server-specific
772
+
information not covered by the standard fields. *)
include Json.Jsonable.S with type t := t
776
+
(** Create a new initialization result
777
+
@param capabilities Server capabilities that define supported optional features
778
+
@param server_info Server implementation details
779
+
@param protocol_version MCP protocol version supported by the server
780
+
@param instructions Optional instructions for using the server
781
+
@param meta Optional additional metadata
782
+
@return A new initialization result
val create : capabilities:Json.t -> server_info:Implementation.t -> protocol_version:string -> ?instructions:string -> ?meta:Json.t -> unit -> t
786
+
(** Convert to JSON-RPC message
787
+
@param id ID matching the original request
788
+
@param t Initialization result
789
+
@return JSON-RPC message containing the initialization result
val to_jsonrpc : id:RequestId.t -> t -> JSONRPCMessage.t
228
-
(** Initialized notification *)
795
+
(** Initialized notification - Completes the initialization phase of the MCP lifecycle *)
module Notification : sig
798
+
(** InitializedNotification is sent by the client after receiving the initialization
799
+
response, indicating it's ready to begin normal operations. This completes the
800
+
three-step initialization process, after which both client and server can
801
+
freely exchange messages according to the negotiated capabilities.
803
+
Only after this notification has been sent should the client begin normal operations
804
+
like listing resources, calling tools, or requesting prompts. *)
807
+
(** Optional additional metadata as arbitrary JSON. Can contain client-specific
808
+
information not covered by the standard fields. *)
include Json.Jsonable.S with type t := t
812
+
(** Create a new initialized notification
813
+
@param meta Optional additional metadata
814
+
@return A new initialized notification
val create : ?meta:Json.t -> unit -> t
818
+
(** Convert to JSON-RPC message
819
+
@param t Initialized notification
820
+
@return JSON-RPC message containing the initialized notification
val to_jsonrpc : t -> JSONRPCMessage.t
241
-
(** Parse a JSON message into an MCP message *)
826
+
(** Parse a JSON message into an MCP message
828
+
This function takes a raw JSON value and parses it into a structured MCP message.
829
+
It's the primary entry point for processing incoming JSON-RPC messages in the MCP protocol.
831
+
The function determines the message type (notification, request, response, or error)
832
+
based on the presence and values of specific fields:
833
+
- A message with "method" but no "id" is a notification
834
+
- A message with "method" and "id" is a request
835
+
- A message with "id" and "result" is a response
836
+
- A message with "id" and "error" is an error
838
+
@param json The JSON message to parse, typically received from the transport layer
839
+
@return The parsed MCP message as a structured JSONRPCMessage.t value
840
+
@raise Parse error if the JSON cannot be parsed as a valid MCP message
val parse_message : Json.t -> JSONRPCMessage.t
244
-
(** Create JSONRPC message helpers *)
844
+
(** Create a new notification message
846
+
Notifications are one-way messages that don't expect a response.
847
+
This is a convenience wrapper around JSONRPCMessage.create_notification.
849
+
Common notifications in MCP include:
850
+
- "notifications/initialized" - Sent after initialization
851
+
- "notifications/progress" - Updates on long-running operations
852
+
- "notifications/resources/updated" - Resource content changed
853
+
- "notifications/prompts/list_changed" - Available prompts changed
854
+
- "notifications/tools/list_changed" - Available tools changed
856
+
@param params Optional parameters for the notification as a JSON value
857
+
@param method_ Method name for the notification, typically following MCP naming conventions
858
+
@return A new JSON-RPC notification message
val create_notification : ?params:Json.t option -> method_:string -> unit -> JSONRPCMessage.t
862
+
(** Create a new request message
864
+
Requests are messages that expect a corresponding response.
865
+
This is a convenience wrapper around JSONRPCMessage.create_request.
867
+
Common requests in MCP include:
868
+
- "initialize" - Start the MCP lifecycle
869
+
- "resources/list" - Discover available resources
870
+
- "resources/read" - Retrieve resource contents
871
+
- "tools/list" - Discover available tools
872
+
- "tools/call" - Invoke a tool
873
+
- "prompts/list" - Discover available prompts
874
+
- "prompts/get" - Retrieve a prompt template
876
+
@param params Optional parameters for the request as a JSON value
877
+
@param progress_token Optional progress token for long-running operations
878
+
that can report progress updates
879
+
@param id Unique identifier for the request, used to correlate with the response
880
+
@param method_ Method name for the request, following MCP naming conventions
881
+
@return A new JSON-RPC request message
val create_request : ?params:Json.t option -> ?progress_token:ProgressToken.t option -> id:RequestId.t -> method_:string -> unit -> JSONRPCMessage.t
885
+
(** Create a new response message
887
+
Responses are sent in reply to requests and contain successful results.
888
+
This is a convenience wrapper around JSONRPCMessage.create_response.
890
+
Each response must include the same ID as its corresponding request
891
+
to allow the client to correlate them, especially when multiple
892
+
requests are in flight simultaneously.
894
+
@param id ID matching the original request
895
+
@param result Result of the successful request as a JSON value
896
+
@return A new JSON-RPC response message
val create_response : id:RequestId.t -> result:Json.t -> JSONRPCMessage.t
900
+
(** Create a new error message
902
+
Errors are sent in reply to requests when processing fails.
903
+
This is a convenience wrapper around JSONRPCMessage.create_error.
905
+
MCP uses standard JSON-RPC error codes as well as some protocol-specific codes:
906
+
- -32700: Parse error (invalid JSON)
907
+
- -32600: Invalid request (malformed JSON-RPC)
908
+
- -32601: Method not found
909
+
- -32602: Invalid parameters
910
+
- -32603: Internal error
911
+
- -32002: Resource not found (MCP-specific)
912
+
- -32001: Authentication required (MCP-specific)
914
+
@param id ID matching the original request
915
+
@param code Error code indicating the type of error
916
+
@param message Human-readable error message describing the issue
917
+
@param data Optional additional error data providing more context
918
+
@return A new JSON-RPC error message
val create_error : id:RequestId.t -> code:int -> message:string -> ?data:Json.t option -> unit -> JSONRPCMessage.t