tree: 4bb915cb896732cd23c7eb324418b52d8f054b44 [search]
  1. example/
  2. lib/
  3. test/
  4. tool/
  5. analysis_options.yaml
  6. CHANGELOG.md
  7. dart_test.yaml
  8. DEVELOPING.md
  9. LICENSE
  10. pubspec.yaml
  11. README.md
pkgs/dart_mcp/README.md

pub package package publisher

A Dart package for making MCP servers and clients.

Note: This package is still experimental and is likely to evolve quickly.

Implementing Servers

To implement a server, import package:dart_mcp/server.dart and extend the MCPServer class. You must provide the server a StreamChannel<Map<String, Object?>> of decoded JSON-RPC messages to send and receive messages with, such as the one returned by stdioChannel from package:dart_mcp/stdio.dart.

For each specific MCP capability or utility your server supports, there is a corresponding mixin that you can use (ToolsSupport, ResourcesSupport, etc).

Each mixin has doc comments explaining how to use it - some may require you to provide implementations of methods, while others may just expose new methods that you can call.

Register server-specific tools, resources, prompts, and request handlers by overriding MCPServer.initialize(MCPServerInitialization). Always call the super method, and declare what your server supports by editing MCPServer.capabilities. This hook can be used independently of the legacy MCP handshake; the context supplies the protocol version, optional client information, and client capabilities for either lifecycle. A request-scoped transport completes MCPServer.initialized by calling handleInitialized() after this hook and any transport-specific setup have finished, or serves each decoded message on a fresh server instance with handleRequestScopedMessage.

MCPServer.initializeLegacy(InitializeRequest) handles protocol negotiation and the legacy initialize response. Override it only when you need to customize that handshake; feature registration belongs in MCPServer.initialize.

See the examples for some example code (server examples end in _server.dart).

Asking the Client for Input

A tool, prompt or resource handler that needs something from the client answers with an InputRequiredResult naming the elicitation, sampling or roots request it wants filled in. On 2026-07-28 the client answers by retrying the request with the responses attached. On earlier revisions the server sends the same requests itself over the connection and reruns the handler with the answers. A handler written this way serves every supported revision.

Check MCPServer.clientCapabilities before asking for something the client did not declare. If your server needs a capability for every call, read the ClientCapabilities passed to MCPServer.initialize through MCPServerInitialization.clientCapabilities and return an error there, which gives the client a better message than a failing tool call.

Implementing Clients

To implement a client, import package:dart_mcp/client.dart and extend the MCPClient class, or directly call its constructor with a Implementation if you aren't implementing any “capabilities”.

For each specific MCP capability your client supports, there is a corresponding mixin that you can use (RootsSupport, SamplingSupport, etc). Each mixin has doc comments explaining how to use it - some may require you to provide implementations of methods, while others may just expose new methods that you can call.

Connecting to Servers

You can connect this client to STDIO servers by passing the channel returned by stdioChannel to MCPClient.connectServer, or any other StreamChannel<Map<String, Object?>> of decoded JSON-RPC messages. The jsonRpcChannel helper in package:dart_mcp/stdio.dart adapts a StreamChannel<String> whose events each contain one complete JSON document.

The returned ServerConnection should be used for all interactions with the server, starting with a call to ServerConnection.initializeAcrossVersions, which settles the protocol version through discovery or the legacy initialize handshake. If a version could not be negotiated or a server does not support required features, the server connection should be closed (by calling ServerConnection.shutdown).

See initialization lifecycle for information about the client/server initialization protocol.

Invoking Server Capabilities and Utilities

All server capabilities and utilities are exposed as methods or streams on the ServerConnection class.

Before attempting to call methods on the server however, you should first verify the capabilities of the server by reading them from the InitializedServer returned from ServerConnection.initializeAcrossVersions.

Supported Protocol Versions

2024-11-05 2025-03-26 2025-06-18 2025-11-25 2026-07-28

2026-07-28 is served over Streamable HTTP, which has no initialize handshake. The stdio handshake still negotiates up to 2025-11-25.

If support for a given protocol version is dropped, that will be released as a breaking change in this package.

However, we will strive to maintain backwards compatibility where possible.

Base Utilities

This table describes the state of implementation for the base protocol utilities.

Both the MCPServer and MCPClient support these.

UtilitySupportNotes
Ping:heavy_check_mark:
Cancellation:construction:A cancelled incoming request stops sending on the wire, and progress goes out only for the request that owns its token. The handler still runs to the end. Sending one is tracked in https://github.com/dart-lang/ai/issues/37
Progress:heavy_check_mark:

Transport Mechanisms

This table describes the supported transport mechanisms.

At its core this package is just built on streams, so any transport mechanism can be used, but some are directly supported out of the box.

TransportSupportNotes
Stdio:heavy_check_mark:
Streamable HTTP:heavy_check_mark:handleStreamableHttpRequest serves requests, answering with an SSE stream when a handler emits related notifications and with a JSON body otherwise. streamableHttpClientChannel posts each client message, reads JSON and SSE responses, reports a failure on its request id or on the channel when there is none, and mirrors x-mcp-header tool parameters. It speaks only 2026-07-28 and does not fall back to an earlier transport.

Batching Requests

Batch requests are not supported. Batching was removed from MCP in protocol version 2025-06-18, and a batch frame is answered with a single invalid request error response, including for clients which negotiated 2025-03-26.

Authorization

Authorization is not supported at this time. This package is primarily targeted at local MCP server usage for now.

Server Capabilities

This table describes the state of implementation for the server capabilities.

Note: Servers can also invoke all client capabilities, see Invoking Client Capabilities.

CapabilitySupportNotes
Prompts:heavy_check_mark:
Resources:heavy_check_mark:
Tools:heavy_check_mark:

Server Utilities

This table describes the state of implementation for the server utilities.

UtilitySupportNotes
Completion:heavy_check_mark:
Logging:heavy_check_mark:
Pagination:construction:https://github.com/dart-lang/ai/issues/28

Client Capabilities

This table describes the state of implementation for the client capabilities.

Note: Clients can also invoke all server capabilities and server utilities, see Invoking Server Capabilities and Utilities.

CapabilitySupportNotes
Roots:heavy_check_mark:
Sampling:heavy_check_mark:
Elicitation:heavy_check_mark:ElicitationFormSupport, ElicitationUrlSupport (elicitations_client.dart)