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```