diff --git a/lib/cli/vide_command_runner.dart b/lib/cli/vide_command_runner.dart index e656f71e..b2215ce0 100644 --- a/lib/cli/vide_command_runner.dart +++ b/lib/cli/vide_command_runner.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:args/args.dart'; import 'package:args/command_runner.dart'; +import 'package:flutter_runtime_mcp/flutter_runtime_mcp.dart'; import 'package:vide_cli/cli/connect_command.dart'; import 'package:vide_cli/cli/serve_command.dart'; import 'package:vide_cli/cli/session_server_command.dart'; @@ -32,7 +33,12 @@ class VideCommandRunner extends CommandRunner { negatable: false, help: 'Force local session mode (ignore daemon setting)', ) - ..addFlag('daemon', negatable: false, help: 'Force daemon session mode'); + ..addFlag('daemon', negatable: false, help: 'Force daemon session mode') + ..addFlag( + 'flutter-mcp', + negatable: false, + help: 'Run as a standalone Flutter MCP server (stdio mode)', + ); addCommand(ServeCommand()); addCommand(ConnectCommand()); @@ -44,6 +50,7 @@ class VideCommandRunner extends CommandRunner { EXAMPLES: vide Launch interactive TUI + vide --flutter-mcp Run Flutter MCP server (stdio) vide serve Start daemon on port 8080 vide serve --port 9000 Start daemon on port 9000 vide serve --generate-token Start with auto-generated auth token @@ -67,6 +74,11 @@ SAFETY: return; } + if (topLevelResults['flutter-mcp'] as bool) { + await FlutterRuntimeServer().startStdio(); + return; + } + if (topLevelResults.command != null) { await super.runCommand(topLevelResults); return; diff --git a/packages/claude_sdk/lib/src/mcp/server/mcp_server_base.dart b/packages/claude_sdk/lib/src/mcp/server/mcp_server_base.dart index d4020a64..4433e5f9 100644 --- a/packages/claude_sdk/lib/src/mcp/server/mcp_server_base.dart +++ b/packages/claude_sdk/lib/src/mcp/server/mcp_server_base.dart @@ -106,6 +106,24 @@ abstract class McpServerBase { } } + /// Start the server in stdio mode (for standalone MCP hosting). + /// + /// Unlike [start], this uses stdin/stdout for communication instead of HTTP. + /// The returned future completes when the transport is closed. + Future startStdio() async { + _mcpServer = McpServer( + Implementation(name: name, version: version), + options: ServerOptions( + capabilities: ServerCapabilities(tools: ServerCapabilitiesTools()), + ), + ); + + registerTools(_mcpServer!); + + final transport = StdioServerTransport(); + await _mcpServer!.connect(transport); + } + /// Stop the server Future stop() async { await onStop(); diff --git a/packages/flutter_runtime_mcp/README.md b/packages/flutter_runtime_mcp/README.md index e12c2d64..6cd6ba41 100644 --- a/packages/flutter_runtime_mcp/README.md +++ b/packages/flutter_runtime_mcp/README.md @@ -24,9 +24,49 @@ dependencies: path: ../packages/flutter_runtime_mcp ``` -## Usage +## Standalone Usage -### Starting the Server +The easiest way to use the Flutter MCP independently is via vide: + +```bash +vide --flutter-mcp +``` + +This starts the Flutter MCP server in stdio mode, ready for any MCP client. + +### Claude Code + +Add to `.claude/settings.local.json`: + +```json +{ + "mcpServers": { + "flutter-runtime": { + "command": "vide", + "args": ["--flutter-mcp"] + } + } +} +``` + +### Claude Desktop + +Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS): + +```json +{ + "mcpServers": { + "flutter-runtime": { + "command": "vide", + "args": ["--flutter-mcp"] + } + } +} +``` + +## Programmatic Usage + +### Starting the Server (HTTP) ```dart import 'package:flutter_runtime_mcp/flutter_runtime_mcp.dart'; @@ -39,6 +79,16 @@ void main() async { } ``` +### Starting the Server (stdio) + +```dart +import 'package:flutter_runtime_mcp/flutter_runtime_mcp.dart'; + +void main() async { + await FlutterRuntimeServer().startStdio(); +} +``` + ### MCP Tools #### flutterStart diff --git a/packages/flutter_runtime_mcp/bin/main.dart b/packages/flutter_runtime_mcp/bin/main.dart index 9dd1638f..244f41d0 100644 --- a/packages/flutter_runtime_mcp/bin/main.dart +++ b/packages/flutter_runtime_mcp/bin/main.dart @@ -1,18 +1,5 @@ import 'package:flutter_runtime_mcp/flutter_runtime_mcp.dart'; -import 'package:mcp_dart/mcp_dart.dart'; void main() async { - final flutterRuntime = FlutterRuntimeServer(); - - final mcpServer = McpServer( - Implementation(name: FlutterRuntimeServer.serverName, version: '1.0.0'), - options: ServerOptions( - capabilities: ServerCapabilities(tools: ServerCapabilitiesTools()), - ), - ); - - flutterRuntime.registerTools(mcpServer); - - final transport = StdioServerTransport(); - await mcpServer.connect(transport); + await FlutterRuntimeServer().startStdio(); }