DS DevShelfHub Projects · AI tools
Tutorials / MCP / Reference / Interfaces / InitializeRequest
Interface lifecycle modelcontextprotocol/types

InitializeRequest

By DevShelfHub

First request a client sends to begin an MCP session.

What is InitializeRequest?

InitializeRequest is the mandatory first message a client sends over a newly opened MCP transport connection. It establishes the shared context for the entire session by advertising the client's supported protocol version, its declared capabilities, and identifying metadata about the client implementation. Until the server processes this message and returns an InitializeResult, the protocol is in a pre-handshake state and no other request types are valid — sending them early is a protocol violation that conformant servers must reject. \n\n Within the MCP message flow, InitializeRequest sits at the very top of the lifecycle: transport opens, client sends InitializeRequest, server replies with InitializeResult, then the client emits the initialized notification to signal it has processed the server's capabilities. Only after that three-step exchange does the session enter the ready state where tools, resources, and prompts can be invoked. The params.protocolVersion field drives version negotiation — the server may accept the proposed version or respond with a version it supports, and the client must decide whether to proceed. \n\n The API surface is intentionally flat at the top level: a literal method string "initialize" and a params object containing three required fields. ClientCapabilities is the extensible object where optional feature support (roots, sampling, experimental) is declared. The clientInfo Implementation object carries name and version strings used for logging and diagnostics. Because this message defines what the session can do, its payload is typically small and latency-sensitive — it should never be deferred or batched.

When to use

Once per session — it MUST be the first request.

When NOT to use

Never re-send during an active session.

Notes

Version negotiation is client-driven

The client proposes a protocolVersion string in the request; the server either echoes it back in InitializeResult or responds with a lower version it supports. Clients must check the version in the response before assuming any capability is available. Hard-coding the latest version string without a fallback path is a common source of breakage when connecting to older server implementations.

No requests before handshake completes

The spec explicitly prohibits sending any request other than InitializeRequest before the initialized notification has been sent by the client. Race conditions in async client code — firing tool calls immediately after connect — will cause servers to return protocol-error responses. In SDKs like the TypeScript MCP SDK, the client.connect() promise does not resolve until the full three-step handshake is complete, protecting against this.

ClientCapabilities controls feature negotiation

Only capabilities declared in the InitializeRequest params.capabilities object are available for the session. For example, if the client omits the sampling capability block, the server must not issue sampling/createMessage requests. Forgetting to declare a capability your handler depends on is a silent failure — the server simply never invokes that path, with no error surfaced.

clientInfo is for diagnostics, not auth

The name and version fields inside clientInfo are informational only — servers should log them for observability but must not use them as an authentication or authorization signal. Malicious clients can supply arbitrary strings. Any access control must be enforced at the transport layer (TLS client certificates, OAuth tokens) before InitializeRequest is even parsed.

Reconnect resets the session entirely

If the underlying transport drops and reconnects, the handshake must be repeated from scratch with a fresh InitializeRequest. There is no resume or re-attach mechanism in the base protocol. Clients that cache session state (tool lists, resource subscriptions) must re-fetch that state after every successful re-initialization.

Fields

Field Type Required Purpose
method 'initialize' yes Method identifier.
params.protocolVersion string yes e.g. '2025-11-25'.
params.capabilities ClientCapabilities yes Optional features the client supports.
params.clientInfo Implementation yes Client identity.

Examples

Initialize handshake

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": { "sampling": {} },
    "clientInfo": { "name": "claude-desktop", "version": "0.7.0" }
  }
}

Common mistakes

❌ Sending tools/list before initialize

✅ Wait for InitializeResult and send notifications/initialized first.

Related

InitializeRequest FAQ

What is InitializeRequest in the MCP protocol?

InitializeRequest is an MCP interface type that defines the structure of protocol data exchanged between MCP clients and servers. It is part of the Model Context Protocol's JSON-RPC 2.0 message schema.

Which package provides the InitializeRequest type?

InitializeRequest is defined in the modelcontextprotocol/types package of the MCP TypeScript SDK. Equivalent types are available in the Python, Kotlin, Go, Ruby, and C# SDK implementations.

When should I use InitializeRequest in my MCP implementation?

Use InitializeRequest when your MCP host, client, or server implementation needs to work with this protocol structure. Refer to the When to use section above and the MCP specification for authoritative guidance.

What fields does InitializeRequest contain?

See the Fields table on this page for a complete list of fields in InitializeRequest, their types, whether they are required or optional, and their purpose.

Where can I find more MCP interface documentation?

The complete MCP API reference on DevShelfHub documents all MCP interfaces, methods, and notifications. Visit the MCP API Reference index to browse all types.