Flutter's API has been stable for years but its widget catalogue has churned, and Dart's move to sound null safety split training data into pre and post eras that do not compile together. An agent needs the Flutter and Dart versions, the state management approach the project actually uses, and whether Material 3 is enabled. Layout errors here are constraint errors rather than style errors, so an agent that does not reason about bounded and unbounded constraints will keep producing overflow warnings it cannot explain.
Scoped read and write access to the project directory.
Reading pubspec.yaml and the analysis options file is how the agent learns the SDK constraint and lint rules it must satisfy.
History, diffs, and blame.
Diffs show which state management pattern the team has been converging on, which the current file layout alone may not reveal.
Reads issues, releases, and pull requests.
Plugin support for a given platform, especially web and desktop, is usually documented only in the plugin's issue tracker.
Pulls crash reports and stack traces.
Dart exceptions from disposed widgets and async gaps appear on real devices long after the frame that caused them.
These are the failures that repeat across sessions, so each one belongs in .mcp.json.
A codebase using Riverpod, Bloc, or Provider will still get StatefulWidget plus setState from an agent, because that is the simplest working answer and the surrounding files may not show the pattern. The result is state that no other widget can observe and that bypasses your testing setup. Add to your rules file: 'This project uses [your solution]. New feature state goes through it. setState is acceptable only for purely local widget concerns such as an animation flag or a text field focus state.'
RaisedButton, FlatButton, OutlineButton, the new keyword, and nullable-by-default parameter handling all still appear in agent output, and none of them compile against a current SDK. The failure is at least loud, but it costs a full round trip every time. State it: 'Flutter 3.x with sound null safety and Material 3. Use ElevatedButton, TextButton, and OutlinedButton. Never emit the new keyword or code that assumes implicit nullability.'
Agents write an async handler that awaits a network call and then calls Navigator.of(context) or shows a SnackBar, without checking that the widget is still mounted. If the user navigated away during the await, this throws or targets a disposed element. Add: 'After any await in a widget or State method, check mounted before touching BuildContext. The use_build_context_synchronously lint must stay enabled and its warnings are errors.'
Agents put a ListView inside a Column, or a Column inside a Column, and hit an unbounded height constraint that renders as a yellow overflow stripe or a hard exception. They then add shrinkWrap: true as a blanket fix, which works visually and destroys scroll performance on long lists. Write: 'Resolve unbounded constraints with Expanded or Flexible, or use CustomScrollView with slivers. shrinkWrap is only for genuinely short, non-scrolling lists and its use needs a comment.'
AnimationController, TextEditingController, ScrollController, and StreamSubscription all get created in initState by agents and then never disposed, which leaks and produces setState-after-dispose errors that surface far from the cause. Add: 'Every controller or subscription created in initState is disposed in dispose. If a widget has initState it must have a matching dispose unless there is nothing to release.'
Agents build widget trees with no const anywhere, so subtrees that never change are rebuilt on every parent rebuild. Nothing breaks, the app just does more work per frame than it needs to, and it compounds in long lists. Write: 'flutter_lints is enabled with prefer_const_constructors and prefer_const_literals_to_create_immutables. Mark every widget const where the analyzer allows it, and run dart analyze before finishing.'