virnavi_ai_agent_compose 0.0.3
virnavi_ai_agent_compose: ^0.0.3 copied to clipboard
Ties Flutter UI to MCP tool results. Widgets rebuild reactively when AI agents invoke tools — no setState needed.
virnavi_ai_agent_compose #
Flutter UI layer for virnavi_ai_agent_mcp.
Ties Flutter widgets to MCP tool results — widgets rebuild reactively when AI agents invoke tools, with no setState needed.
Features #
McpToolState— sealed state type representingidle,loading,success(data), anderror(message).McpResultStore—ChangeNotifierthat holds per-tool state and notifies listeners on every transition.McpComposeBinding— wrapsToolDefinitionhandlers to drive state throughidle → loading → success | errorautomatically.McpResultBuilder— Flutter widget that rebuilds whenever a specific tool's state changes.McpViewDefinition— pairs a model ID with aWidget Function(Object?)builder for use withMcpSummary.McpSummaryViewsX— extension onMcpSummarythat attaches view definitions viabindViews()and exposesbuildView().@McpViewannotation re-exported — app code only needs to import this package.
Getting started #
Add to pubspec.yaml:
dependencies:
virnavi_ai_agent_mcp: ^0.0.1
virnavi_ai_agent_compose: ^0.0.1
dev_dependencies:
build_runner: ^2.4.0
virnavi_ai_agent_mcp_generator: ^0.0.1
Usage #
1. Set up the store and binding #
final store = McpResultStore();
final binding = McpComposeBinding(store);
final bridge = AgentBridge.instance;
// Register tools so their state flows through the binding:
service.mcpTools.registerWith(bridge, binding);
2. Display results reactively #
McpResultBuilder(
store: store,
toolName: 'packages/my_app/mcp/tasks/list',
builder: (context, state) => switch (state) {
McpIdle() => const Text('Waiting…'),
McpLoading() => const CircularProgressIndicator(),
McpSuccess(:final data) => TaskCard(result: data as Task),
McpError(:final message) => Text('Error: $message'),
},
)
3. Use @McpView + McpSummary for automatic wiring (with generator) #
Annotate your result widget:
// task_card.dart
import 'package:flutter/material.dart';
import 'package:virnavi_ai_agent_compose/virnavi_ai_agent_compose.dart';
import 'models.dart';
part 'task_card.mcp.dart';
@McpView(modelType: Task)
class TaskCard extends StatelessWidget {
final Task result;
const TaskCard({super.key, required this.result});
@override
Widget build(BuildContext context) => ListTile(title: Text(result.title));
}
After running dart run build_runner build, use the generated summary:
final summary = $AppSummaryMcpSummary.bindWithViews(service.mcpTools);
summary.tools.values.toList().registerWith(bridge, binding);
// Build a view for any tool result by model ID:
final widget = summary.buildView('my_app/Task', data);
License #
MIT — see LICENSE.