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

ClientCapabilities

By DevShelfHub

Declares the optional features the client supports, sent during initialize.

What is ClientCapabilities?

ClientCapabilities is the client-side declaration of optional MCP features, transmitted once inside the initialize request before any other protocol traffic. It functions as a capability contract: the server reads this object and limits its behavior strictly to what the client has advertised. If a client omits a capability field entirely, the server must treat the feature as unsupported and must never invoke it — there is no fallback negotiation round-trip after initialization completes. In the message flow, ClientCapabilities travels as the capabilities property of InitializeParams. The server inspects it, then responds with its own ServerCapabilities object, completing the symmetric handshake. This means the capabilities you declare here directly gate which server-side features become active for the session lifetime: omitting roots means the server will not call roots/list, omitting sampling means the server will not issue createMessage requests back to the client, and omitting elicitation means the server will skip any form or URL-based elicitation flows. The type has grown incrementally across spec versions. The roots field acquired a listChanged sub-flag to signal support for roots/listChanged notifications separately from basic roots access. The elicitation field is newer still, with form and url sub-flags tracking two distinct elicitation delivery modes. Experimental is an open-ended escape hatch for pre-spec extensions; treat any key under it as unstable across server implementations.

When to use

Always — every initialize request carries a ClientCapabilities object.

When NOT to use

Never lie about capabilities — declare only what you actually support.

Notes

Omission equals explicit denial

A missing capability field is not ambiguous — servers that follow the spec treat absence the same as { }. Never rely on server-side defaulting to fill in omitted flags. If your client builds ClientCapabilities dynamically, audit every conditional branch to ensure features the user has enabled are actually included in the outgoing object.

roots.listChanged is a separate contract

Declaring roots without listChanged means the server knows you can respond to roots/list but will not send you roots/listChanged notifications. If your client updates its workspace roots at runtime, you must set listChanged: true or the server will cache the initial list forever. Forgetting this flag is a common source of stale-context bugs in long-running sessions.

sampling and elicitation carry security weight

Advertising sampling grants the server permission to call createMessage back on your client, which executes an LLM completion on behalf of server logic. Advertising elicitation permits the server to surface forms or URLs to your end user. Both capabilities should be considered consent grants, not just protocol hints — only declare them if your client has the UX and authorization model to handle incoming requests safely.

experimental keys are opaque to the spec

The experimental field has type Record<string, object>, so both key names and value shapes are entirely implementation-defined. Two servers using the same key may interpret its value differently. Validate experimental payloads defensively on both sides and version-gate any behavior you build on top of them, since they can disappear or change shape without a spec revision.

Compare with ServerCapabilities symmetry

ServerCapabilities mirrors this type but covers server-side features like tools, resources, prompts, and logging. The two types are intentionally asymmetric: clients advertise consumer capabilities (what they can receive), servers advertise producer capabilities (what they can serve). Understanding the distinction avoids the mistake of looking for tools or resources inside ClientCapabilities when inspecting a captured initialize exchange.

Fields

Field Type Required Purpose
experimental object? no Map of experimental capability names → settings.
roots { listChanged?: boolean }? no Whether the client provides filesystem roots.
sampling object? no Whether the client can fulfil sampling/createMessage requests.
elicitation { form?, url? }? no Whether the client can render elicitation forms or URL flows.
tasks object? no Whether the client supports task-augmented requests.

Examples

Full capabilities declaration

json
{
  "roots": { "listChanged": true },
  "sampling": {},
  "elicitation": { "form": {} }
}

Common mistakes

❌ Declaring sampling:{} without implementing the handler

✅ Only declare features that are wired up — servers will call them.

Related

ClientCapabilities FAQ

What is ClientCapabilities in the MCP protocol?

ClientCapabilities 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 ClientCapabilities type?

ClientCapabilities 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 ClientCapabilities in my MCP implementation?

Use ClientCapabilities 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 ClientCapabilities contain?

See the Fields table on this page for a complete list of fields in ClientCapabilities, 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.