flutter_mcp_server 0.1.2 copy "flutter_mcp_server: ^0.1.2" to clipboard
flutter_mcp_server: ^0.1.2 copied to clipboard

Flutter plugin for implementing Model Context Protocol (MCP) servers. Provides tools to build MCP servers that can expose data, functionality, and interaction patterns to LLM applications.

example/lib/main.dart

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

import 'package:flutter/services.dart';
import 'package:flutter_mcp_server/flutter_mcp_server.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  bool _serverRunning = false;
  String _statusMessage = 'Server not running';
  List<String> _logs = [];

  McpServer? _server;

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    String platformVersion;
    // Platform messages may fail, so we use a try/catch PlatformException.
    // We also handle the message potentially returning null.
    try {
      platformVersion =
          await FlutterMcpServer.getPlatformVersion() ?? 'Unknown platform version';
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  void _startServer() {
    // Create MCP server
    _server = FlutterMcpServer.createServer(
      name: 'Example MCP Server',
      version: '1.0.0',
      capabilities: ServerCapabilities(
        tools: true,
        resources: true,
        prompts: true,
      ),
    );

    // Add a simple calculator tool
    _server!.addTool(
      name: 'calculator',
      description: 'Perform basic calculations',
      inputSchema: {
        'type': 'object',
        'properties': {
          'operation': {
            'type': 'string',
            'enum': ['add', 'subtract', 'multiply', 'divide'],
          },
          'a': {'type': 'number'},
          'b': {'type': 'number'},
        },
        'required': ['operation', 'a', 'b'],
      },
      handler: (arguments) async {
        final operation = arguments['operation'] as String;
        final a = arguments['a'] as num;
        final b = arguments['b'] as num;

        _addLog('Calculator tool called: $operation $a $b');

        double result;
        switch (operation) {
          case 'add':
            result = (a + b).toDouble();
            break;
          case 'subtract':
            result = (a - b).toDouble();
            break;
          case 'multiply':
            result = (a * b).toDouble();
            break;
          case 'divide':
            if (b == 0) {
              return CallToolResult(
                content: [TextContent(text: 'Division by zero error')],
                isError: true,
              );
            }
            result = (a / b).toDouble();
            break;
          default:
            return CallToolResult(
              content: [TextContent(text: 'Unknown operation: $operation')],
              isError: true,
            );
        }

        return CallToolResult(
          content: [TextContent(text: result.toString())],
        );
      },
    );

    // Add a time resource
    _server!.addResource(
      uri: 'time://current',
      name: 'Current Time',
      description: 'Get the current date and time',
      mimeType: 'text/plain',
      handler: (uri, params) async {
        _addLog('Time resource accessed: $uri');
        final now = DateTime.now().toString();

        return ReadResourceResult(
          contents: [
            ResourceContent(
              resource: Resource(
                uri: uri.toString(),
                name: 'Current Time',
                mimeType: 'text/plain',
              ),
            ),
          ],
        );
      },
    );

    // Add a greeting prompt
    _server!.addPrompt(
      name: 'greeting',
      description: 'Generate a customized greeting',
      arguments: [
        PromptArgument(
          name: 'name',
          description: 'Name to greet',
          required: true,
        ),
        PromptArgument(
          name: 'language',
          description: 'Language for greeting',
          required: false,
        ),
      ],
      handler: (arguments) async {
        final name = arguments?['name'] as String? ?? 'User';
        final language = arguments?['language'] as String? ?? 'English';

        _addLog('Greeting prompt called: $name in $language');

        String greeting;
        switch (language.toLowerCase()) {
          case 'spanish':
            greeting = '¡Hola, $name!';
            break;
          case 'french':
            greeting = 'Bonjour, $name!';
            break;
          case 'german':
            greeting = 'Guten Tag, $name!';
            break;
          default:
            greeting = 'Hello, $name!';
        }

        return GetPromptResult(
          description: 'A greeting in $language',
          messages: [
            Message(
              role: MessageRole.user,
              content: TextContent(text: greeting),
            ),
          ],
        );
      },
    );

    // Connect to transport
    final transport = FlutterMcpServer.createStdioTransport();
    _server!.connect(transport).then((_) {
      _addLog('Server connected to stdio transport');
      setState(() {
        _serverRunning = true;
        _statusMessage = 'Server running on stdio transport';
      });
    }).catchError((e) {
      _addLog('Error connecting server: $e');
      setState(() {
        _statusMessage = 'Error: $e';
      });
    });
  }

  void _stopServer() {
    if (_server != null) {
      _server!.disconnect().then((_) {
        _addLog('Server disconnected');
        setState(() {
          _serverRunning = false;
          _statusMessage = 'Server stopped';
          _server = null;
        });
      }).catchError((e) {
        _addLog('Error disconnecting server: $e');
      });
    }
  }

  void _addLog(String message) {
    setState(() {
      _logs.add('${DateTime.now().toString()}: $message');
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter MCP Server Example'),
        ),
        body: Column(
          children: [
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: Text('Running on: $_platformVersion'),
            ),
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ElevatedButton(
                    onPressed: _serverRunning ? null : _startServer,
                    child: const Text('Start Server'),
                  ),
                  const SizedBox(width: 16),
                  ElevatedButton(
                    onPressed: _serverRunning ? _stopServer : null,
                    child: const Text('Stop Server'),
                  ),
                ],
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: Text(
                _statusMessage,
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  color: _serverRunning ? Colors.green : Colors.red,
                ),
              ),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text(
                      'Server Logs:',
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                    const SizedBox(height: 8),
                    Expanded(
                      child: Container(
                        decoration: BoxDecoration(
                          border: Border.all(color: Colors.grey),
                          borderRadius: BorderRadius.circular(8),
                        ),
                        padding: const EdgeInsets.all(8),
                        child: ListView.builder(
                          itemCount: _logs.length,
                          itemBuilder: (context, index) {
                            return Text(_logs[index]);
                          },
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
1
likes
130
points
28
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for implementing Model Context Protocol (MCP) servers. Provides tools to build MCP servers that can expose data, functionality, and interaction patterns to LLM applications.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, flutter_web_plugins, http, json_annotation, path_provider, uuid, web_socket_channel

More

Packages that depend on flutter_mcp_server

Packages that implement flutter_mcp_server