Model Context Protocol in OCaml
1--- 2title: Lifecycle 3type: docs 4weight: 30 5--- 6 7{{< callout type="info" >}} **Protocol Revision**: 2025-03-26 {{< /callout >}} 8 9The Model Context Protocol (MCP) defines a rigorous lifecycle for client-server 10connections that ensures proper capability negotiation and state management. 11 121. **Initialization**: Capability negotiation and protocol version agreement 132. **Operation**: Normal protocol communication 143. **Shutdown**: Graceful termination of the connection 15 16```mermaid 17sequenceDiagram 18 participant Client 19 participant Server 20 21 Note over Client,Server: Initialization Phase 22 activate Client 23 Client->>+Server: initialize request 24 Server-->>Client: initialize response 25 Client--)Server: initialized notification 26 27 Note over Client,Server: Operation Phase 28 rect rgb(200, 220, 250) 29 note over Client,Server: Normal protocol operations 30 end 31 32 Note over Client,Server: Shutdown 33 Client--)-Server: Disconnect 34 deactivate Server 35 Note over Client,Server: Connection closed 36``` 37 38## Lifecycle Phases 39 40### Initialization 41 42The initialization phase **MUST** be the first interaction between client and server. 43During this phase, the client and server: 44 45- Establish protocol version compatibility 46- Exchange and negotiate capabilities 47- Share implementation details 48 49The client **MUST** initiate this phase by sending an `initialize` request containing: 50 51- Protocol version supported 52- Client capabilities 53- Client implementation information 54 55```json 56{ 57 "jsonrpc": "2.0", 58 "id": 1, 59 "method": "initialize", 60 "params": { 61 "protocolVersion": "2024-11-05", 62 "capabilities": { 63 "roots": { 64 "listChanged": true 65 }, 66 "sampling": {} 67 }, 68 "clientInfo": { 69 "name": "ExampleClient", 70 "version": "1.0.0" 71 } 72 } 73} 74``` 75 76The initialize request **MUST NOT** be part of a JSON-RPC 77[batch](https://www.jsonrpc.org/specification#batch), as other requests and notifications 78are not possible until initialization has completed. This also permits backwards 79compatibility with prior protocol versions that do not explicitly support JSON-RPC 80batches. 81 82The server **MUST** respond with its own capabilities and information: 83 84```json 85{ 86 "jsonrpc": "2.0", 87 "id": 1, 88 "result": { 89 "protocolVersion": "2024-11-05", 90 "capabilities": { 91 "logging": {}, 92 "prompts": { 93 "listChanged": true 94 }, 95 "resources": { 96 "subscribe": true, 97 "listChanged": true 98 }, 99 "tools": { 100 "listChanged": true 101 } 102 }, 103 "serverInfo": { 104 "name": "ExampleServer", 105 "version": "1.0.0" 106 } 107 } 108} 109``` 110 111After successful initialization, the client **MUST** send an `initialized` notification 112to indicate it is ready to begin normal operations: 113 114```json 115{ 116 "jsonrpc": "2.0", 117 "method": "notifications/initialized" 118} 119``` 120 121- The client **SHOULD NOT** send requests other than 122 [pings]({{< ref "utilities/ping" >}}) before the server has responded to the 123 `initialize` request. 124- The server **SHOULD NOT** send requests other than 125 [pings]({{< ref "utilities/ping" >}}) and 126 [logging]({{< ref "../server/utilities/logging" >}}) before receiving the `initialized` 127 notification. 128 129#### Version Negotiation 130 131In the `initialize` request, the client **MUST** send a protocol version it supports. 132This **SHOULD** be the _latest_ version supported by the client. 133 134If the server supports the requested protocol version, it **MUST** respond with the same 135version. Otherwise, the server **MUST** respond with another protocol version it 136supports. This **SHOULD** be the _latest_ version supported by the server. 137 138If the client does not support the version in the server's response, it **SHOULD** 139disconnect. 140 141#### Capability Negotiation 142 143Client and server capabilities establish which optional protocol features will be 144available during the session. 145 146Key capabilities include: 147 148| Category | Capability | Description | 149| -------- | -------------- | -------------------------------------------------------------------------- | 150| Client | `roots` | Ability to provide filesystem [roots]({{< ref "../client/roots" >}}) | 151| Client | `sampling` | Support for LLM [sampling]({{< ref "../client/sampling" >}}) requests | 152| Client | `experimental` | Describes support for non-standard experimental features | 153| Server | `prompts` | Offers [prompt templates]({{< ref "../server/prompts" >}}) | 154| Server | `resources` | Provides readable [resources]({{< ref "../server/resources" >}}) | 155| Server | `tools` | Exposes callable [tools]({{< ref "../server/tools" >}}) | 156| Server | `logging` | Emits structured [log messages]({{< ref "../server/utilities/logging" >}}) | 157| Server | `experimental` | Describes support for non-standard experimental features | 158 159Capability objects can describe sub-capabilities like: 160 161- `listChanged`: Support for list change notifications (for prompts, resources, and 162 tools) 163- `subscribe`: Support for subscribing to individual items' changes (resources only) 164 165### Operation 166 167During the operation phase, the client and server exchange messages according to the 168negotiated capabilities. 169 170Both parties **SHOULD**: 171 172- Respect the negotiated protocol version 173- Only use capabilities that were successfully negotiated 174 175### Shutdown 176 177During the shutdown phase, one side (usually the client) cleanly terminates the protocol 178connection. No specific shutdown messages are defined—instead, the underlying transport 179mechanism should be used to signal connection termination: 180 181#### stdio 182 183For the stdio [transport]({{< ref "transports" >}}), the client **SHOULD** initiate 184shutdown by: 185 1861. First, closing the input stream to the child process (the server) 1872. Waiting for the server to exit, or sending `SIGTERM` if the server does not exit 188 within a reasonable time 1893. Sending `SIGKILL` if the server does not exit within a reasonable time after `SIGTERM` 190 191The server **MAY** initiate shutdown by closing its output stream to the client and 192exiting. 193 194#### HTTP 195 196For HTTP [transports]({{< ref "transports" >}}), shutdown is indicated by closing the 197associated HTTP connection(s). 198 199## Timeouts 200 201Implementations **SHOULD** establish timeouts for all sent requests, to prevent hung 202connections and resource exhaustion. When the request has not received a success or error 203response within the timeout period, the sender **SHOULD** issue a [cancellation 204notification]({{< ref "utilities/cancellation" >}}) for that request and stop waiting for 205a response. 206 207SDKs and other middleware **SHOULD** allow these timeouts to be configured on a 208per-request basis. 209 210Implementations **MAY** choose to reset the timeout clock when receiving a [progress 211notification]({{< ref "utilities/progress" >}}) corresponding to the request, as this 212implies that work is actually happening. However, implementations **SHOULD** always 213enforce a maximum timeout, regardless of progress notifications, to limit the impact of a 214misbehaving client or server. 215 216## Error Handling 217 218Implementations **SHOULD** be prepared to handle these error cases: 219 220- Protocol version mismatch 221- Failure to negotiate required capabilities 222- Request [timeouts](#timeouts) 223 224Example initialization error: 225 226```json 227{ 228 "jsonrpc": "2.0", 229 "id": 1, 230 "error": { 231 "code": -32602, 232 "message": "Unsupported protocol version", 233 "data": { 234 "supported": ["2024-11-05"], 235 "requested": "1.0.0" 236 } 237 } 238} 239```