MCP ExplorerExplorer

Flutter Mcp

@app-appplayeron a year ago
1 MIT
FreeCommunity
AI Systems
A Flutter plugin for integrating LLMs with MCP, supporting background tasks and notifications.

Overview

What is Flutter Mcp

flutter_mcp is a Flutter plugin designed for integrating Large Language Models (LLMs) with the Model Context Protocol (MCP). It facilitates seamless interaction between MCP components and various platform-specific features.

Use cases

Use cases for flutter_mcp include developing intelligent mobile applications, creating desktop applications with background processing, implementing notification systems, and managing application lifecycles effectively.

How to use

To use flutter_mcp, add it to your pubspec.yaml file under dependencies or install it via command line. Initialize the plugin in your Flutter application and configure it according to your needs, such as enabling background services and notifications.

Key features

Key features include seamless MCP integration, support for multiple clients and servers, background service execution, local notifications, system tray support, application lifecycle management, secure storage, task scheduling, memory management, performance monitoring, and cross-platform support.

Where to use

flutter_mcp can be used in applications that require integration with Large Language Models, such as chatbots, virtual assistants, and any software needing advanced language processing capabilities.

Content

Flutter MCP

🙌 Support This Project

If you find this package useful, consider supporting ongoing development on Patreon.

Support on Patreon

🔗 MCP Dart Package Family

  • mcp_server: Exposes tools, resources, and prompts to LLMs. Acts as the AI server.
  • mcp_client: Connects Flutter/Dart apps to MCP servers. Acts as the client interface.
  • mcp_llm: Bridges LLMs (Claude, OpenAI, etc.) to MCP clients/servers. Acts as the LLM brain.
  • flutter_mcp: Complete Flutter plugin for MCP integration with platform features.
  • flutter_mcp_ui_core: Core models, constants, and utilities for Flutter MCP UI system.
  • flutter_mcp_ui_runtime: Comprehensive runtime for building dynamic, reactive UIs through JSON specifications.
  • flutter_mcp_ui_generator: JSON generation toolkit for creating UI definitions with templates and fluent API.

A Flutter plugin for integrating Large Language Models (LLMs) with Model Context Protocol (MCP). This plugin provides comprehensive integration between MCP components and platform-specific features like background execution, notifications, system tray, and lifecycle management.

Features

  • MCP Integration:

    • Built-in MCP client, server, and LLM capabilities (no need for separate packages)
    • Support for multiple simultaneous MCP clients and servers
    • LLM integration with MCP components
    • Enhanced batch processing with priority-based deduplication
  • Platform Features:

    • Background service execution with task queuing
    • Local notifications with enhanced configuration
    • System tray support with dynamic menu management (desktop platforms)
    • Application lifecycle management with health monitoring
    • Secure storage for credentials and configuration
  • Advanced Capabilities:

    • Real-time Health Monitoring: Component-level health tracking with event-driven updates
    • Enhanced Error Handling: Circuit breaker pattern with automatic recovery strategies
    • Resource Management: Automatic cleanup with leak detection and memory optimization
    • Performance Monitoring: Advanced metrics with aggregation, anomaly detection, and threshold alerts
    • Plugin System: Version management, sandboxing, and dependency resolution
    • Security Features: Comprehensive audit logging, encryption management, and risk assessment
    • Type Safety: Typed platform channels eliminating manual JSON handling
    • Dynamic Configuration: Runtime config updates with validation and rollback support
    • Cross-platform support: Android, iOS, macOS, Windows, Linux, Web

Getting Started

Installation

Add the package to your pubspec.yaml:

dependencies:
  flutter_mcp: ^1.0.3

Or install via command line:

flutter pub add flutter_mcp

Platform Setup (Optional)

Android Configuration

You can configure Android-specific settings in your pubspec.yaml:

Foreground Service Types

By default, flutter_mcp uses dataSync foreground service type which works for most use cases. If you need additional service types (e.g., location, mediaPlayback), add this to your pubspec.yaml:

flutter_mcp:
  android:
    foreground_service_types:
      - dataSync      # Default - data synchronization
      - location      # For location-based services
      - mediaPlayback # For media playback
      - microphone    # For audio recording
Additional Permissions (Coming Soon)

In future versions, you’ll be able to request additional Android permissions through pubspec.yaml:

flutter_mcp:
  android:
    permissions:
      - camera        # For camera access
      - location      # For location services
      - microphone    # For audio recording
      - storage       # For file access

These configurations are automatically applied during build time. No manual AndroidManifest.xml changes needed!

Basic Usage

import 'package:flutter/material.dart';
import 'package:flutter_mcp/flutter_mcp.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize Flutter MCP
  await FlutterMCP.instance.init(
    MCPConfig(
      appName: 'My MCP App',
      appVersion: '1.0.0',
      useBackgroundService: true,
      useNotification: true,
      useTray: true,
      autoStart: true,
      enablePerformanceMonitoring: true, // Enable performance monitoring
      highMemoryThresholdMB: 512, // Set memory threshold for automatic cleanup
      // Auto-start server configuration
      autoStartServer: [
        MCPServerConfig(
          name: 'MCP Server',
          version: '1.0.0',
          capabilities: ServerCapabilities(
            tools: true,
            resources: true,
            prompts: true,
          ),
          integrateLlm: MCPLlmIntegration(
            providerName: 'your-provider',
            config: LlmConfiguration(
              apiKey: 'your-api-key',
              model: 'your-model',
            ),
          ),
        ),
      ],
      // Auto-start client configuration
      autoStartClient: [
        MCPClientConfig(
          name: 'MCP Client',
          version: '1.0.0',
          capabilities: ClientCapabilities(
            sampling: true,
            roots: true,
          ),
          integrateLlm: MCPLlmIntegration(
            existingLlmId: 'llm_1',
          ),
        ),
      ],
      // Scheduled tasks
      schedule: [
        MCPJob.every(
          Duration(minutes: 15),
          task: () {
            // This runs every 15 minutes
          },
        ),
      ],
      // System tray configuration
      tray: TrayConfig(
        tooltip: 'My MCP App',
        menuItems: [
          TrayMenuItem(label: 'Show', onTap: () {
            // Show window code
          }),
          TrayMenuItem.separator(),
          TrayMenuItem(label: 'Exit', onTap: () {
            // Exit app code
          }),
        ],
      ),
    ),
  );
  
  runApp(MyApp());
}

Manual Component Creation

You can also manually create and manage MCP components:

import 'package:logging/logging.dart';

// Create a logger
final logger = Logger('flutter_mcp.example');

// Create a server
final serverId = await FlutterMCP.instance.createServer(
  name: 'MCP Server',
  version: '1.0.0',
  capabilities: ServerCapabilities(
    tools: true,
    resources: true,
    prompts: true,
  ),
);

// Create a client
final clientId = await FlutterMCP.instance.createClient(
  name: 'MCP Client',
  version: '1.0.0',
  transportCommand: 'server',
  transportArgs: ['--port', '8080'],
);

// Create an LLM
final llmId = await FlutterMCP.instance.createLlm(
  providerName: 'openai',
  config: LlmConfiguration(
    apiKey: 'your-api-key',
    model: 'gpt-4o',
  ),
);

// Connect components
await FlutterMCP.instance.integrateServerWithLlm(
  serverId: serverId,
  llmId: llmId,
);

await FlutterMCP.instance.integrateClientWithLlm(
  clientId: clientId,
  llmId: llmId,
);

// Start components
FlutterMCP.instance.connectServer(serverId);
await FlutterMCP.instance.connectClient(clientId);

// Use components with memory-efficient caching
final response = await FlutterMCP.instance.chat(
  llmId,
  'Hello, how are you today?',
  useCache: true, // Enable caching for repeated questions
);
logger.info('AI: ${response.text}');

// Stream responses from LLM
Stream<LlmResponseChunk> responseStream = FlutterMCP.instance.streamChat(
  llmId,
  'Write me a short story about robots',
);

responseStream.listen((chunk) {
  logger.info(chunk.textChunk); // Process each chunk as it arrives
});

// Clean up when done
await FlutterMCP.instance.shutdown();

Platform Support

Platform Background Service Notifications System Tray
Android
iOS ⚠️ (Limited)
macOS
Windows
Linux

Transport Configuration

Transport is the core communication mechanism in MCP. Flutter MCP supports three transport types, each with its own configuration options.

Transport Types

Transport Type Description Use Case
STDIO Standard Input/Output communication Local process communication, subprocess execution
SSE Server-Sent Events over HTTP Real-time streaming, web-compatible communication
StreamableHTTP HTTP with streaming support REST-like API with streaming capabilities

Server Transport Configuration

STDIO Server

final serverId = await FlutterMCP.instance.createServer(
  name: 'STDIO Server',
  version: '1.0.0',
  config: MCPServerConfig(
    name: 'STDIO Server',
    version: '1.0.0',
    transportType: 'stdio',  // Required: must be explicitly specified
  ),
);

SSE Server

final serverId = await FlutterMCP.instance.createServer(
  name: 'SSE Server',
  version: '1.0.0',
  config: MCPServerConfig(
    name: 'SSE Server',
    version: '1.0.0',
    transportType: 'sse',    // Required: must be explicitly specified
    ssePort: 8080,           // Required for SSE
    host: 'localhost',       // Optional: default 'localhost'
    endpoint: '/sse',        // Optional: default '/sse'
    messagesEndpoint: '/message',  // Optional: default '/message'
    fallbackPorts: [8081, 8082],   // Optional: alternative ports
    authToken: 'secret',     // Optional: authentication
    middleware: [],          // Optional: custom middleware
  ),
);

StreamableHTTP Server

final serverId = await FlutterMCP.instance.createServer(
  name: 'StreamableHTTP Server',
  version: '1.0.0',
  config: MCPServerConfig(
    name: 'StreamableHTTP Server',
    version: '1.0.0',
    transportType: 'streamablehttp',  // Required: must be explicitly specified
    streamableHttpPort: 8080,         // Required for StreamableHTTP
    host: 'localhost',                // Optional: default 'localhost'
    endpoint: '/mcp',                 // Optional: default '/mcp'
    messagesEndpoint: '/message',     // Optional: default '/message'
    fallbackPorts: [8081, 8082],      // Optional: alternative ports
    authToken: 'secret',              // Optional: authentication
    isJsonResponseEnabled: false,     // Optional: false = SSE mode (default), true = JSON mode
    jsonResponseMode: 'sync',         // Optional: 'sync' or 'async' (only for JSON mode)
    maxRequestSize: 4194304,          // Optional: max request size in bytes (default 4MB)
    requestTimeout: Duration(seconds: 30),  // Optional: request timeout
    corsConfig: {                     // Optional: CORS configuration
      'allowOrigin': '*',
      'allowMethods': 'POST, GET, OPTIONS',
      'allowHeaders': 'Content-Type, Authorization',
    },
  ),
);

Client Transport Configuration

STDIO Client

final clientId = await FlutterMCP.instance.createClient(
  name: 'STDIO Client',
  version: '1.0.0',
  config: MCPClientConfig(
    name: 'STDIO Client',
    version: '1.0.0',
    transportType: 'stdio',        // Required: must be explicitly specified
    transportCommand: 'python',    // Required for STDIO
    transportArgs: ['server.py', '--mode', 'mcp'],  // Optional: command arguments
  ),
);

SSE Client

final clientId = await FlutterMCP.instance.createClient(
  name: 'SSE Client',
  version: '1.0.0',
  config: MCPClientConfig(
    name: 'SSE Client',
    version: '1.0.0',
    transportType: 'sse',              // Required: must be explicitly specified
    serverUrl: 'http://localhost:8080', // Required for SSE
    endpoint: '/sse',                  // Optional: will be appended to serverUrl
    authToken: 'secret',               // Optional: authentication
    headers: {                         // Optional: additional headers
      'X-Custom-Header': 'value',
    },
    timeout: Duration(seconds: 30),    // Optional: request timeout
    sseReadTimeout: Duration(minutes: 5),  // Optional: SSE stream timeout
  ),
);

StreamableHTTP Client

final clientId = await FlutterMCP.instance.createClient(
  name: 'StreamableHTTP Client',
  version: '1.0.0',
  config: MCPClientConfig(
    name: 'StreamableHTTP Client',
    version: '1.0.0',
    transportType: 'streamablehttp',    // Required: must be explicitly specified
    serverUrl: 'http://localhost:8080', // Required for StreamableHTTP (base URL only)
    endpoint: '/mcp',                   // Optional: server should use the same endpoint
    authToken: 'secret',                // Optional: authentication
    headers: {                          // Optional: additional headers
      'X-Custom-Header': 'value',
    },
    timeout: Duration(seconds: 30),     // Optional: request timeout
    maxConcurrentRequests: 10,          // Optional: max concurrent requests
    useHttp2: true,                     // Optional: use HTTP/2 if available
    terminateOnClose: true,             // Optional: terminate session on close
  ),
);

Important Notes

  1. Transport Type is Required: Starting from v1.0.1, transportType must be explicitly specified. Automatic inference has been removed to prevent unexpected behavior.

  2. URL Handling:

    • For SSE: The endpoint is appended to serverUrl if provided
    • For StreamableHTTP: The client connects to the base serverUrl, and the server’s endpoint configuration must match
  3. Default Endpoints:

    • SSE Server: /sse (messages) and /message (commands)
    • StreamableHTTP Server: /mcp (all communications)
  4. Authentication: All transports support bearer token authentication via the authToken field

  5. Port Configuration:

    • Servers can specify fallbackPorts for automatic failover
    • Clients connect to the specific port in the serverUrl

Connection Example

// 1. Create and start a StreamableHTTP server
final serverId = await FlutterMCP.instance.createServer(
  name: 'My Server',
  version: '1.0.0',
  config: MCPServerConfig(
    name: 'My Server',
    version: '1.0.0',
    transportType: 'streamablehttp',
    streamableHttpPort: 8080,
    endpoint: '/mcp',  // Server listens at http://localhost:8080/mcp
  ),
);
await FlutterMCP.instance.connectServer(serverId);

// 2. Create and connect a client to the server
final clientId = await FlutterMCP.instance.createClient(
  name: 'My Client',
  version: '1.0.0',
  config: MCPClientConfig(
    name: 'My Client',
    version: '1.0.0',
    transportType: 'streamablehttp',
    serverUrl: 'http://localhost:8080',  // Base URL only
    endpoint: '/mcp',  // Must match server's endpoint
  ),
);
await FlutterMCP.instance.connectClient(clientId);

Permissions

Flutter MCP automatically requests necessary permissions based on your configuration:

Automatic Permission Handling

When you enable features in MCPConfig, permissions are requested automatically during initialization:

  • useNotification: true → Requests notification permission
  • useBackgroundService: true → Requests background execution permissions (Android 13+)

Manual Permission Management

You can also manage permissions manually:

// Check specific permission
bool hasNotificationPermission = await FlutterMCP.instance.checkPermission('notification');

// Request specific permission
bool granted = await FlutterMCP.instance.requestPermission('notification');

// Request multiple permissions
Map<String, bool> results = await FlutterMCP.instance.requestPermissions([
  'notification',
  'location',
]);

// Request all required permissions based on current config
Map<String, bool> results = await FlutterMCP.instance.requestRequiredPermissions();

Platform-specific Notes

  • Android: Permissions are defined in AndroidManifest.xml. Runtime permissions (like notifications on Android 13+) are requested automatically.
  • iOS: Permissions must be described in Info.plist. Runtime permissions are requested when needed.
  • Desktop: Most features don’t require explicit permissions, except for system tray on some Linux distributions.

Configuration Options

MCPConfig Options

MCPConfig(
  appName: 'My App',
  appVersion: '1.0.0',
  useBackgroundService: true,
  useNotification: true,
  useTray: true,
  secure: true,
  lifecycleManaged: true,
  autoStart: true,
  enablePerformanceMonitoring: true,
  enableMetricsExport: false,
  highMemoryThresholdMB: 512,
  lowBatteryWarningThreshold: 20,
  maxConnectionRetries: 3,
  llmRequestTimeoutMs: 60000,
  background: BackgroundConfig(...),
  notification: NotificationConfig(...),
  tray: TrayConfig(...),
  schedule: [...],
  autoStartServer: [...],
  autoStartClient: [...],
)

Logging Configuration

Flutter MCP uses the standard Dart logging package following MCP conventions:

import 'package:flutter_mcp/flutter_mcp.dart';
import 'package:logging/logging.dart';

// Configure logging
FlutterMcpLogging.configure(
  level: Level.INFO,
  enableDebugLogging: true, // Sets level to FINE
);

// Create a logger with MCP naming convention
final Logger logger = Logger('flutter_mcp.my_component');

// Use the logger
logger.info('Information message');
logger.warning('Warning message');
logger.severe('Error message');
logger.fine('Debug message');
logger.finest('Trace message');

// Extension methods for compatibility
logger.debug('Debug message');  // Maps to fine()
logger.error('Error message');  // Maps to severe()
logger.warn('Warning message'); // Maps to warning()
logger.trace('Trace message');  // Maps to finest()

Background Service Configuration

BackgroundConfig(
  notificationChannelId: 'my_channel',
  notificationChannelName: 'My Channel',
  notificationDescription: 'Background service notification',
  notificationIcon: 'app_icon',
  autoStartOnBoot: true,
  intervalMs: 5000,
  keepAlive: true,
)

Notification Configuration

NotificationConfig(
  channelId: 'notifications_channel',
  channelName: 'Notifications',
  channelDescription: 'App notifications',
  icon: 'notification_icon',
  enableSound: true,
  enableVibration: true,
  priority: NotificationPriority.high,
)

System Tray Configuration

TrayConfig(
  iconPath: 'assets/tray_icon.png',
  tooltip: 'My MCP App',
  menuItems: [
    TrayMenuItem(label: 'Show', onTap: showApp),
    TrayMenuItem.separator(),
    TrayMenuItem(label: 'Exit', onTap: exitApp),
  ],
)

Advanced Usage

Memory-Efficient Processing

// Process large data in chunks to avoid memory spikes
final documents = [...]; // List of documents
final processedDocs = await FlutterMCP.instance.processDocumentsInChunks(
  documents,
  (doc) async {
    // Process each document
    return processedDocument;
  },
  chunkSize: 10,
  pauseBetweenChunks: Duration(milliseconds: 100),
);

Memory-Aware Caching

// Chat with memory-aware caching for faster responses
// The cache will automatically reduce in size during high memory conditions
final response = await FlutterMCP.instance.chat(
  llmId,
  userMessage,
  useCache: true,
);

Performance Monitoring

import 'package:logging/logging.dart';

final logger = Logger('flutter_mcp.example');

// Get system performance metrics
final status = FlutterMCP.instance.getSystemStatus();
logger.info('Memory usage: ${status['performanceMetrics']['resources']['memory.usageMB']['current']}MB');
logger.info('LLM response time: ${status['performanceMetrics']['timers']['llm.chat']['avg_ms']}ms');

Secure Storage

// Store values securely
await FlutterMCP.instance.secureStore('api_key', 'your-secret-api-key');

// Retrieve values
final apiKey = await FlutterMCP.instance.secureRead('api_key');

Task Scheduling

// Add scheduled tasks
final jobId = FlutterMCP.instance.addScheduledJob(
  MCPJob.every(
    Duration(hours: 1),
    task: () {
      // Perform regular task
    },
  ),
);

// Schedule one-time tasks
FlutterMCP.instance.addScheduledJob(
  MCPJob.once(
    Duration(minutes: 5),
    task: () {
      // Will execute only once after 5 minutes
    },
  ),
);

// Remove scheduled tasks
FlutterMCP.instance.removeScheduledJob(jobId);

System Status

import 'package:logging/logging.dart';

final logger = Logger('flutter_mcp.example');

// Get system status
final status = FlutterMCP.instance.getSystemStatus();
logger.info('Clients: ${status['clients']}');
logger.info('Servers: ${status['servers']}');
logger.info('LLMs: ${status['llms']}');
logger.info('Platform: ${status['platformName']}');
logger.info('Memory: ${status['performanceMetrics']['resources']['memory.usageMB']['current']}MB');

Plugin Registration

// Register custom plugins
await FlutterMCP.instance.registerPlugin(
  MyCustomPlugin(),
  {'config_key': 'value'},
);

// Execute custom tool plugins
final result = await FlutterMCP.instance.executeToolPlugin(
  'my_tool_plugin',
  {'param1': 'value1'},
);

Examples

Check out the example directory for a complete sample application.

Configuration Examples

Scheduled Tasks Configuration

{
  "schedule": [
    {
      "id": "health_check",
      "name": "System Health Check",
      "intervalMinutes": 15,
      "taskType": "healthcheck",
      "taskConfig": {
        "checks": [
          "memory",
          "connectivity",
          "services"
        ]
      }
    },
    {
      "id": "cleanup_task",
      "name": "Cleanup Temporary Files",
      "intervalHours": 6,
      "taskType": "cleanup",
      "taskConfig": {
        "targets": [
          "temp",
          "cache",
          "logs"
        ]
      }
    },
    {
      "id": "memory_monitor",
      "name": "Memory Usage Check",
      "intervalMinutes": 5,
      "taskType": "memory_check"