If you've used Riverpod for any non-trivial Flutter app, you've probably hit this moment: a provider's state looks wrong, and you have no idea which other provider triggered the update, or why it rebuilt at all. print statements and breakpoints only get you so far when the bug involves a chain of watch/read/listen relationships.
I built riverpod_devtools to fix that — a Flutter DevTools extension that gives you a live, visual view of your providers. Plus, as of v0.6.0, it bundles an optional MCP server so AI coding tools like Claude Code can read that exact same data.
I've been building and iterating on it on pub.dev for about five months now (it's already at v0.6.0 across nine releases), but I haven't actually written about it or shared it anywhere until today — this is its first real introduction. Feedback, issues, and stars are very welcome.
🚀 What it does
Once it's wired up, a riverpod_devtools tab shows up in Flutter DevTools with three panels:
- Provider Graph — visualizes dependencies between providers (who watches/reads/listens to whom)
- State Inspector — the current state of any selected provider, with type labels and a collapsible JSON tree for complex objects
-
Event Log — a hierarchical, real-time log of provider lifecycle events (
added,updated,disposed), grouped so related sub-events don't get lost in the noise
It supports both light and dark themes, and works with both Riverpod 2.x and 3.x.
🔍 Why static analysis instead of runtime detection
Earlier versions tried to infer provider dependencies by watching update timing at runtime — which works, until two providers update close together for unrelated reasons and you get a false edge in the graph.
0.5.0 replaced that with a CLI tool that does AST-based static analysis of your actual source code:
# one-time
dart run riverpod_devtools:analyze
# or watch mode while you work
dart run riverpod_devtools:analyze --watch
This walks your code with the analyzer package, finds every ref.watch / ref.read / ref.listen call, and emits a lib/riverpod_dependencies.json with exact dependency types and source locations (file/line/column). No heuristics, no false positives — the graph reflects what your code actually does, not what it looked like it did at runtime.
🛠️ Quick start
1. Add the dependency
dependencies:
riverpod_devtools: ^0.6.0
flutter_riverpod: '>=2.3.0 <4.0.0'
2. Wire it up in main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
try {
final jsonString = await rootBundle.loadString(
'lib/riverpod_dependencies.json',
);
RiverpodDevToolsRegistry.instance.loadFromJson(jsonString);
} catch (_) {
// DevTools shows setup instructions if this hasn't been generated yet
}
runApp(
ProviderScope(
observers: [RiverpodDevToolsObserver()],
child: const MyApp(),
),
);
}
Run the app, open Flutter DevTools, and the riverpod_devtools tab is there automatically. Full setup (including the pubspec.yaml asset entry) is in the README.
🤖 The part I'm most excited about: an MCP server for your provider logs
This is new in 0.6.0, and it's the reason I wanted to write this up rather than just quietly ship it.
RiverpodDevToolsObserver already starts a local, debug-only HTTP server (localhost:8788) to feed the DevTools UI. 0.6.0 adds a bundled MCP server executable that relays that same data over MCP — so tools like Claude Code can read your app's live provider events directly.
Setup is one .mcp.json entry:
{
"mcpServers": {
"riverpod_devtools_mcp": {
"type": "stdio",
"command": "dart",
"args": ["run", "riverpod_devtools:riverpod_devtools_mcp"]
}
}
}
(or claude mcp add --scope project riverpod_devtools_mcp -- dart run riverpod_devtools:riverpod_devtools_mcp)
Run your app in debug mode, and Claude Code can now call get_riverpod_logs to pull buffered provider_added / provider_updated / provider_disposed events, and clear_riverpod_logs to reset the buffer before reproducing a specific flow. In practice that means you can say something like:
"Reproduce the checkout flow, then look at the current provider logs and tell me why
cartTotalProviderisn't updating afterremoveItem."
...and the agent actually has runtime ground truth instead of guessing from source code alone.
Current limitations: HTTP-only on localhost, native platforms only (no web), and real devices/emulators need manual port forwarding (adb forward / iproxy) since they don't share the host's loopback. Full details in MCP.md.
🎯 Try it
flutter pub add riverpod_devtools
- pub.dev: pub.dev/packages/riverpod_devtools
- GitHub: github.com/yutsuki3/riverpod_devtools
- Issues / feedback: github.com/yutsuki3/riverpod_devtools/issues
It's MIT-licensed and still early — the Provider Graph and MCP integration in particular could use real-world testing across different app sizes. If you use Riverpod, I'd genuinely appreciate you trying it on an existing project and telling me what breaks or what's missing.

Top comments (0)