Client class

Main MCP Client class that handles all client-side protocol operations

Available extensions

Constructors

Client({required String name, required String version, String? description, String? title, String? websiteUrl, List<McpIcon>? icons, ClientCapabilities capabilities = const ClientCapabilities(), String? protocolVersion, Duration requestTimeout = const Duration(seconds: 30), Duration maxRequestTimeout = const Duration(minutes: 10)})
Creates a new MCP client with the specified parameters

Properties

cacheResults ↔ bool
Caching (2026-07-28): keep cacheable results while their ttlMs says they are fresh. Off by default. One client is one authorization context; call clearResultCache when its credentials change (an authentication-required error clears it too).
getter/setter pair
capabilities → ClientCapabilities
Client capabilities configuration
final
description → String?
Spec 2025-11-25+: optional human-readable description of this client implementation. Emitted on clientInfo during initialize when set; older peers ignore it (additive).
final
era → ProtocolEra
The era this client settled on for the connection.
no setter
eraProbeTimeout ↔ Duration?
How long the server/discover era probe waits before treating the server as legacy (an unknown pre-initialize request may get no answer). Null: 30 s on stdio — a server process may still be starting (compiling, even), and its silence then says nothing about its revision — and 5 s elsewhere. A legacy server normally answers the probe at once with an error, so the wait only matters for one that never answers.
getter/setter pair
hashCode → int
The hash code for this object.
no setterinherited
icons → List<McpIcon>?
Icons for the client (clientInfo.icons, 2025-11-25+).
final
isConnected → bool
Whether the client is currently connected
no setter
isStateless → bool
Whether this client is operating in the 2026-07-28 stateless mode.
no setter
maxRequestTimeout → Duration
The longest any request waits, progress notwithstanding (lifecycle, timeouts: enforce a maximum regardless of progress).
final
name → String
Name of the MCP client
final
negotiatedProtocolVersion → String?
Negotiated protocol revision after initialize completes; null before then.
no setter
onConnect → Stream<ServerInfo>
Stream of connection events
no setter
onDisconnect → Stream<DisconnectReason>
Stream of disconnection events
no setter
onElicitationComplete → Stream<String>
elicitationIds the server reports complete (notifications/elicitation/complete), for URL-mode elicitations this client accepted or received in a URL-elicitation-required error. Ids it does not know, or already saw complete, are ignored.
no setter
onError → Stream<McpError>
Stream of error events
no setter
protocolVersion → String
Protocol version this client speaks on this connection.
final
requestTimeout → Duration
How long a request waits for its response unless the request sets its own (RequestOptions.timeout). A progress notification for the request restarts the wait, but never past maxRequestTimeout from the start.
final
roots → List<Root>
Locally configured roots (URI / filesystem boundaries the server is allowed to operate in). Mutations push notifications/roots/list_changed to the server.
no setter
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
serverCapabilities → ServerCapabilities?
Get the server capabilities
no setter
serverInfo → Map<String, dynamic>?
Get the server information
no setter
supportsTasks → bool
no setter
title → String?
Display name for the client (clientInfo.title, 2025-06-18+).
final
validateToolOutput ↔ bool
Whether callTool checks structuredContent against the tool's outputSchema (from the last tools/list). Clients should validate structured results; a mismatch fails the call with McpError.
getter/setter pair
version → String
Version of the MCP client implementation
final
websiteUrl → String?
The client's website (clientInfo.websiteUrl, 2025-11-25+).
final

Methods

addRoot(Root root) → void
Add a root to the client's local list. When the client declared rootsListChanged, the server is told with notifications/roots/list_changed (not on 2026-07-28, which has no such notification).
addRootMap(Map<String, dynamic> root) → void
Map-based variant of addRoot for callers that don't have the typed Root available. Constructs a Root from the supplied map (must contain at least uri) and delegates to addRoot.
callTool(String name, Map<String, dynamic> toolArguments, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<CallToolResult>
Call a tool on the server
callToolAsTask(String name, Map<String, dynamic> toolArguments, {int? ttl, Map<String, dynamic>? meta, RequestOptions? options}) → Future<Task>
Call name as a 2025-11-25 task: the answer is the task, the result comes from taskResult. Only where the server accepts tool tasks and the tool allows them (tools/list is read when the tool is unknown).
callToolWithTracking(String name, Map<String, dynamic> arguments, {bool trackProgress = true, Map<String, dynamic>? meta, RequestOptions? options}) → Future<ToolCallTracking>
Call a tool and get the operation ID for tracking progress
cancelTask(String taskId, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<Task?>
Cancel a task (tasks/cancel). 2025-11-25 answers with the cancelled task; the 2026-07-28 extension only acknowledges (null).
clearResultCache() → void
Drop every cached result.
complete(Map<String, dynamic> ref, Map<String, dynamic> argument, {Map<String, dynamic>? context, Map<String, dynamic>? meta, RequestOptions? options}) → Future<CompleteResult>
Requests completion candidates for one argument of a prompt or resource reference (completion/complete).
connect(ClientTransport transport, {ProtocolEra era = ProtocolEra.auto, bool? statelessMode}) → Future<void>
Connect the client to a transport.
connectWithRetry(Future<ClientTransport> openTransport(), {int maxRetries = 3, Duration delay = const Duration(seconds: 2), ProtocolEra era = ProtocolEra.auto}) → Future<void>
Connect, retrying a failed attempt up to maxRetries times in all.
disconnect() → void
Disconnect the client from its transport
discover({RequestOptions? options}) → Future<DiscoverResult>
2026-07-28 stateless core: fetch the server's supported versions, capabilities, and optional instructions via server/discover.
dispose() → void
Dispose client resources
getPrompt(String name, [Map<String, dynamic>? promptArguments, Map<String, dynamic>? meta, RequestOptions? options]) → Future<GetPromptResult>
Get a prompt from the server
getResourceWithTemplate(String templateUri, Map<String, dynamic> params, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<ReadResourceResult>
Get a resource using a template
getTask(String taskId, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<GetTaskResult>
Poll a task's current state (tasks/get): the task plus, in the extension, inputRequests / result / error for its state.
initialize() → Future<void>
Initialize the connection to the server
listen(SubscriptionFilter filter) → Future<Subscription>
Open a 2026-07-28 subscriptions/listen stream (SEP-2577) — the stateless replacement for the resources/subscribe RPC + the HTTP GET SSE stream.
listPrompts({Map<String, dynamic>? meta, RequestOptions? options}) → Future<List<Prompt>>
List available prompts on the server
listPromptsPage({String? cursor, Map<String, dynamic>? meta, RequestOptions? options}) → Future<ListPromptsResult>
One page of prompts/list: pass the previous page's nextCursor as cursor for the next one.
listResources({Map<String, dynamic>? meta, RequestOptions? options}) → Future<List<Resource>>
List available resources on the server
listResourcesPage({String? cursor, Map<String, dynamic>? meta, RequestOptions? options}) → Future<ListResourcesResult>
One page of resources/list: pass the previous page's nextCursor as cursor for the next one.
listResourceTemplates({Map<String, dynamic>? meta, RequestOptions? options}) → Future<List<ResourceTemplate>>
List resource templates on the server
listResourceTemplatesPage({String? cursor, Map<String, dynamic>? meta, RequestOptions? options}) → Future<ListResourceTemplatesResult>
One page of resources/templates/list: pass the previous page's nextCursor as cursor for the next one.
listTasksPage({String? cursor, RequestOptions? options}) → Future<ListTasksResult>
2025-11-25 tasks/list: one page of this client's tasks.
listTools({Map<String, dynamic>? meta, RequestOptions? options}) → Future<List<Tool>>
List available tools on the server
listToolsMetadata(ToolRegistry registry) → Future<List<ToolMetadata>>

Available on Client, provided by the ClientToolMetadataExtension extension

Fetch tools and return metadata only Caches full tools in provided registry for later schema lookup
listToolsPage({String? cursor, Map<String, dynamic>? meta, RequestOptions? options}) → Future<ListToolsResult>
One page of tools/list: pass the previous page's nextCursor as cursor for the next one.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
notifyCancelled(Object requestId, {String? reason}) → void
Cancel an in-flight server-side operation.
notifyProgress(dynamic progressToken, double progress, {double? total, String? message}) → void
Report progress on an in-flight server-initiated request (spec notifications/progress). progressToken is the token the server sent in the original request's _meta.progressToken.
onElicitationRequest(Future<Map<String, dynamic>> handler(Map<String, dynamic> params)) → void
Register a handler for server-initiated elicitation/create requests (spec 2025-06-18). The handler shows the requested form to the user and returns { action, content? } per spec — action is accept / decline / cancel.
onElicitationRequestTyped(Future<ElicitResult> handler(ElicitRequestParams request)) → void
Typed variant of onElicitationRequest. The handler receives the request params — ElicitRequestFormParams (form mode; each field of requestedSchema.properties reads as a PrimitiveSchemaDefinition) or ElicitRequestURLParams (mode: "url", 2025-11-25) — and returns an ElicitResult.
onListRoots(Future<List<Root>> handler()) → void
Register a custom handler for server-initiated roots/list requests. By default the client responds with the locally configured roots list — supply this to override. Either way the client answers only when it declared roots in its ClientCapabilities.
onListRootsMap(Future<List<Map<String, dynamic>>> handler()) → void
Map-based variant of onListRoots. The handler returns the raw list of root maps (each with at least a uri key); this method wraps it in the spec response shape. Sibling to onSamplingRequestMap — same rationale.
onLogging(dynamic handler(McpLogLevel, String, String?, Map<String, dynamic>?)) → void
Handle logging notification
onNotification(String method, dynamic handler(Map<String, dynamic>)) → void
Register a notification handler
onProgress(dynamic handler(String progressToken, double progress, String message)) → void
Register a handler for progress updates from the server (the 2.x form).
onProgressNotification(void handler(ProgressNotificationParams progress)) → void
Register a handler for progress updates from the server: the whole notifications/progress params (token, progress, total, message).
onPromptsListChanged(dynamic handler()) → void
Handle prompts list changed notification
onResourceContentUpdated(dynamic handler(String uri, ResourceContents content)) → void
Register a handler for notifications/resources/updated that carries the new content: the handler gets the resource's URI and its contents. A notification without content (the usual case) does not reach it — use onResourceUpdated for those.
onResourcesListChanged(dynamic handler()) → void
Handle resources list changed notification
onResourceUpdated(dynamic handler(String)) → void
Handle resource updated notification
onRootsListChanged(dynamic handler()) → void
Handle roots list changed notification
onSamplingRequest(Future<CreateMessageResult> handler(CreateMessageRequestParams request)) → void
Register a handler for server-initiated sampling/createMessage requests. The driver app (Claude Desktop / Claude Code / a vibe-style IDE) fulfils the prompt with its own LLM and returns the spec CreateMessageResult (role, content, model, optional stopReason).
onSamplingRequestMap(Future<Map<String, dynamic>> handler(Map<String, dynamic> params)) → void
Map-based variant of onSamplingRequest. Receives the request's params as a raw map and must return the raw CreateMessageResult map.
onToolsListChanged(dynamic handler()) → void
Handle tools list changed notification
ping({Map<String, dynamic>? meta, RequestOptions? options}) → Future<void>
Sends ping and completes when the peer answers.
readResource(String uri, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<ReadResourceResult>
Read a resource from the server
removeRoot(String uri) → void
Remove a root from the client's local list. Server is notified via notifications/roots/list_changed.
setLoggingLevel(McpLogLevel level, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<void>
Set the logging level for the server
startKeepAlive(Duration interval, {Duration timeout = const Duration(seconds: 10), int maxMissed = 1}) → void
Ping the server every interval (basic/utilities/ping: implementations should check connection health periodically, at a configurable rate). A ping not answered within timeout is missed; maxMissed misses in a row are a connection failure: it is logged and the client disconnects with DisconnectReason.pingTimeout. An answered ping resets the count. Off unless started; revisions without ping (2026-07-28) refuse it.
stopKeepAlive() → void
Stop startKeepAlive pings.
subscribeResource(String uri, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<void>
Subscribe to a resource
taskFromResult(Map<String, dynamic> result) → Task?
If a tools/call (or other) result is a CreateTaskResult — the extension's resultType: "task" or the 2025-11-25 core's nested task — returns the Task; otherwise null.
taskResult(String taskId, {RequestOptions? options}) → Future<Map<String, dynamic>>
2025-11-25 tasks/result: wait for the task to end and return what the underlying request returned (its JSON-RPC error is thrown as McpError).
toString() → String
A string representation of this object.
inherited
unsubscribeResource(String uri, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<void>
Unsubscribe from a resource
updateTask(String taskId, Map<String, dynamic> inputResponses, {Map<String, dynamic>? meta, RequestOptions? options}) → Future<void>
Deliver input responses to an input_required task (tasks/update). inputResponses is keyed by the task's outstanding inputRequests keys.

Operators

operator ==(Object other) → bool
The equality operator.
inherited