πŸ”Œ dart_mcp_client

pub package Dart CI License: MIT

A lightweight, pure Dart client implementation of the Model Context Protocol (MCP) standard.

Works with any LLM framework or Dart backend/CLI/desktop application. Supports both local subprocesses (Stdio) and remote servers (Streamable HTTP / SSE) with zero Flutter or platform dependencies.


✨ Features

  • πŸš€ Dual Transport Support:
    • Stdio (StdioMcpClient): Launch and communicate with local Node.js (npx), Python (uvx), or native binary MCP servers.
    • HTTP (HttpMcpClient): Connect to remote MCP servers over Streamable HTTP and Server-Sent Events (SSE) (MCP 2025 specification).
  • πŸ› οΈ Complete Protocol Implementation:
    • tools/list & tools/call for tool discovery and execution.
    • resources/list & resources/read for context and document access.
    • prompts/list & prompts/get for templated prompt retrieval.
  • πŸ›‘οΈ Battle-Tested Architecture:
    • Request/Response pairing with timeout protection.
    • Windows command resolution (runInShell for .cmd/.bat).
    • Diagnostic logging and real-time stderr streaming.
    • Fail-closed error handling and clean disconnects.

πŸ“¦ Installation

Add dart_mcp_client to your pubspec.yaml:

dependencies:
  dart_mcp_client: ^1.0.0

Or install via Dart CLI:

dart pub add dart_mcp_client

πŸš€ Quick Start

1. Connecting to a Local Stdio Server (e.g. Memory Server)

import 'package:dart_mcp_client/dart_mcp_client.dart';

void main() async {
  final config = McpServerConfig(
    id: 'memory-server',
    name: 'Memory Server',
    transport: McpTransport.stdio,
    command: 'npx',
    args: ['-y', '@modelcontextprotocol/server-memory'],
  );

  final client = StdioMcpClient(
    config,
    onLog: (msg) => print('[LOG] $msg'),
    onStderr: (err) => print('[STDERR] $err'),
  );

  // Connect and perform initial handshake
  await client.connect();

  // Discover available tools
  final tools = await client.getTools();
  for (final tool in tools) {
    print('Discovered tool: ${tool.name} - ${tool.description}');
  }

  // Call a tool
  final result = await client.callTool('create_graph', {});
  print('Result: ${result.text}');

  // Disconnect when done
  await client.disconnect();
}

2. Connecting to a Remote HTTP Server

import 'package:dart_mcp_client/dart_mcp_client.dart';

void main() async {
  final config = McpServerConfig(
    id: 'remote-weather',
    name: 'Weather MCP',
    transport: McpTransport.http,
    url: 'https://api.example.com/mcp',
  );

  final client = HttpMcpClient(config);
  await client.connect();

  final tools = await client.getTools();
  final weather = await client.callTool('get_forecast', {'city': 'Istanbul'});
  print(weather.text);

  await client.disconnect();
}

πŸ—οΈ Architecture

graph TD
    A[Dart App / LLM Agent] --> B[McpClientBase]
    B --> C[StdioMcpClient]
    B --> D[HttpMcpClient]
    C -->|stdin / stdout JSON-RPC| E[Local MCP Server (npx / uvx / binary)]
    D -->|HTTP POST & SSE Streams| F[Remote MCP Server]

πŸ§ͺ Testing

Run the test suite:

dart test

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Libraries

dart_mcp_client
A lightweight, pure Dart Model Context Protocol (MCP) client.