This document outlines the high-level architecture of the dart_mcp_server and its underlying core library dart_mcp.
The Dart MCP Server is an implementation of the Model Context Protocol (MCP). It acts as a bridge between an AI-assistant client (like the Antigravity CLI or an IDE plugin) and the Dart/Flutter development environment.
flowchart LR Client[AI Client] <-->|JSON-RPC 2.0 over stdio| Server[Dart MCP Server] subgraph Dart MCP Server Router[JSON-RPC Router] Tools[Tool Handlers] Resources[Resource Handlers] Prompts[Prompt Handlers] Router <--> Tools Router <--> Resources Router <--> Prompts end Tools --> DartCLI[Dart CLI] Tools --> FlutterCLI[Flutter CLI] Tools --> DTD[Dart Tooling Daemon] Tools --> Analyzer[Language Server Protocol]
The project is split into two primary packages:
dart_mcp: The foundational library implementing the MCP specification. It provides base classes for both Clients and Servers, defining the API types, JSON-RPC communication, and standard MCP capabilities (Tools, Resources, Prompts, etc.) via mixins.dart_mcp_server: The concrete implementation of a server tailored for Dart and Flutter. It extends the base MCPServer and implements specific tools (like hotReload, analyzeFiles, launchApp) by interacting with the Dart CLI, Flutter CLI, and the Dart Tooling Daemon (DTD).The server uses a heavily mixin-based architecture. This allows for clean separation of concerns, where each MCP capability and each set of tools can be developed and maintained independently.
classDiagram class MCPBase { <<abstract>> +registerMethod() +sendRequest() +sendNotification() } class MCPServer { <<abstract>> +initialize() } class ToolsSupport { <<mixin>> +registerTool() +unregisterTool() } class ResourcesSupport { <<mixin>> +addResource() +updateResource() +removeResource() } class PromptsSupport { <<mixin>> +registerPrompt() +unregisterPrompt() } class LoggingSupport { <<mixin>> +log() } class RootsTrackingSupport { <<mixin>> +updateRoots() } class DartMCPServer { +run() } class FlutterLauncherSupport { <<mixin>> +launchApp +stopApp +listDevices +getAppLogs +listRunningApps } class DartAnalyzerSupport { <<mixin>> +analyzeFiles +lsp } class DartToolingDaemonSupport { <<mixin>> +dtd +getRuntimeErrors +getActiveLocation +hotRestart +hotReload +widgetInspector +flutterDriver +callVmServiceMethod } class PubSupport { <<mixin>> +pub } class PubDevSearchSupport { <<mixin>> +pubDevSearch } class AnalyticsSupport { <<mixin>> +analytics } MCPBase <|-- MCPServer MCPServer <|-- DartMCPServer ToolsSupport <|-- DartMCPServer : with ResourcesSupport <|-- DartMCPServer : with PromptsSupport <|-- DartMCPServer : with LoggingSupport <|-- DartMCPServer : with RootsTrackingSupport <|-- DartMCPServer : with FlutterLauncherSupport <|-- DartMCPServer : with DartAnalyzerSupport <|-- DartMCPServer : with DartToolingDaemonSupport <|-- DartMCPServer : with PubSupport <|-- DartMCPServer : with PubDevSearchSupport <|-- DartMCPServer : with AnalyticsSupport <|-- DartMCPServer : with
dart_mcp MixinsThe foundational package provides mixins corresponding to MCP specification features:
ToolsSupport: Allows registering tools that the LLM can call.ResourcesSupport: Manages exposing local data and files to the client as resources.PromptsSupport: Provides a list of pre-defined prompts to the client.LoggingSupport: Structured server-to-client log messages.RootsTrackingSupport: Tracks the client's project roots to provide workspace context to tools.dart_mcp_server MixinsThe concrete server composes tools by mixing in specialized feature sets:
FlutterLauncherSupport: App lifecycle management (launchApp, stopApp, listDevices).DartAnalyzerSupport: Static analysis of Dart code (analyzeFiles).DartToolingDaemonSupport: Dart Tooling Daemon integration for hot reload, hot restart, and widget tree inspection.PubSupport: Package management tools.PubDevSearchSupport: Querying packages from pub.dev.AnalyticsSupport: Telemetry and usage tracking.The DartToolingDaemonSupport mixin is responsible for bridging the MCP server with the Dart Tooling Daemon. DTD serves as a central hub for communication between various Dart tools, IDEs, and running Dart/Flutter applications.
Auto-Discovery and Connection: When the MCP server connects to a DTD instance, it subscribes to DTD service events (like ConnectedAppServiceConstants.vmServiceRegistered) and Editor streams. This allows the MCP server to automatically discover any Dart or Flutter apps connected to that DTD instance, regardless of whether they were launched by an IDE, the CLI, or the MCP server itself. The server automatically establishes VM Service connections to these newly discovered apps and tracks them.
Supported Features:
hotReload and hotRestart on connected applications.getRuntimeErrors tool monitors the VM service error stream, capturing and providing access to recent runtime exceptions for the apps.widgetInspector tool interacts with the ext.flutter.inspector service extension to fetch the widget tree, select widgets, and change the selection mode.callVmServiceMethod tool allows making arbitrary, raw RPC calls to the VM service of a connected app.The DartAnalyzerSupport mixin integrates the Dart Language Server Protocol (LSP) into the MCP server. Rather than running a one-off analysis pass, it starts and manages a persistent dart language-server process.
Persistent Workspace Analysis: When the client's project workspace roots change (tracked via the RootsTrackingSupport mixin), the analyzer mixin dynamically updates the LSP workspace folders. The server remains active in the background, listening for file changes and diagnostics.
Supported Features:
analyzeFiles tool queries the LSP server for current workspace diagnostics. It can also request the LSP server to apply quick fixes (dart.edit.fixAllInWorkspace), which the MCP server translates into filesystem edits via workspace/applyEdit events from the language server.lsp tool exposes deep IDE-like capabilities, including:hover: Provides documentation and type information for a specific position in the code.signatureHelp: Returns parameter information for function calls.resolveWorkspaceSymbol: Enables searching for classes, methods, and variables across the entire workspace.When a client wants to invoke a tool, the request flows through the base communication layer into the specific mixin that registered the tool.
sequenceDiagram participant AI as AI Client participant Base as MCPBase (JSON-RPC) participant Server as DartMCPServer participant Mixin as Tool Mixin (e.g., Dtd) participant Exec as External Process (e.g., DTD) AI->>Base: Request `tools/call` (name: "hotReload") Base->>Server: Route request to Tool Handler Server->>Mixin: Invoke registered callback Mixin->>Exec: Call actual service (e.g., ext.flutter.app.hotReload) Exec-->>Mixin: Return Result / Status Mixin-->>Server: Return MCP ToolResult Server-->>Base: Format as JSON-RPC Response Base-->>AI: Response
By default, the dart_mcp_server communicates with clients over standard input/output (stdio). The lib/stdio.dart utility in dart_mcp creates a StreamChannel wrapping stdin and stdout, which the MCPBase uses for JSON-RPC 2.0 message passing. This allows the server to be seamlessly spawned as a subprocess by clients like the Antigravity CLI or IDE extensions.