flutter_mcp_ui_core 0.6.5 copy "flutter_mcp_ui_core: ^0.6.5" to clipboard
flutter_mcp_ui_core: ^0.6.5 copied to clipboard

Core models, constants, and utilities for Flutter MCP UI system. Shared foundation for renderer and generator packages.

0.6.5 - 2026-08-23 #

Added — location action type (UI DSL §4.25, Location Profile) #

  • ActionTypes.location and ActionTypes.locationTypes, its own list for the same reason as paymentTypes: the Profile is not implied by Core, so a runtime that does not claim it fails the action visibly rather than dropping it as an unknown type. It is still in all, or a validator built from this class would reject a conformant document.
  • The generated widget schema carries location in the action-type enum, so a document using it loads. The enum is derived from §17.2.2 — this is a regeneration, not a hand edit.

payment is declared (DSL §4.24, Payment Profile) #

ActionTypes.payment, carried in its own paymentTypes list. The Payment Profile is not implied by Core, so grouping it with the version lists would have said the wrong thing; it is still in all, because a validator built from this class has to accept a conformant document.

DefinitionValidator reads the action catalog instead of a copy of it #

The known-type set was a literal that stopped at v1.1, so validateAction reported submit, event, identity, sound.* and media.* as unknown types while the runtime executed all of them. It now reads ActionTypes.all, which is also why payment needed no second edit here.

Regenerated #

widgets_schema.g.dart — the action-type enum inside the widget schema is what the runtime's load gate checks, so a document carrying payment would have been rejected before rendering without this.

0.6.4 - 2026-08-11 #

The constants describe the registry again #

WidgetTypes was missing 37 canonical widget typesview, accordion, fileInput, qrCode, link, menu, the animation family, the v1.4 advanced set. isValidType is built from categories, and both are exported, so UIValidator and DefinitionValidator rejected valid 1.4 documents and WidgetRegistry filed those types under no category at all. All 37 are declared and categorised.

ActionTypes gained the canonical grouped forms §17.3.4 names — channel, permission, identity — which existed only in their dotted legacy spellings here, plus submit (§4.22, resolved by the widget rather than the dispatcher) and event (§4.23).

The generated schemas caught up with their source #

widgets_schema.g.dart and the app / page / theme constants are emitted from the yaml registry, and the latter three had not been regenerated since the asset-reference work: they still described AssetRef as five fixed schemes, with no object form, no open scheme set and no Color definition. They now match configs/. Registry-side changes carried in the same regeneration: box accepts decoratedBox / constrainedBox, progressBar accepts circularProgressIndicator and defaults indicatorType to circular, and TableRow is a named shape.

Tests #

The completeness tests counted category lengths (layout == 29, coreTypes == 10). Any 29 layout widgets satisfied that, which is how 37 types went missing under a green suite. They now read the registry and §17.2.2 and compare against them.

0.6.3 - 2026-08-08 — an edge is {from, to} #

The widget-spec registry described a graph edge as {source, target, label} while §10.12 / §10.13 and the generated reference say {from, to}. Both spellings render — the runtime reads the canonical pair first and falls back to the legacy one — so nothing was broken; an author simply could not tell which was the standard, and the two documents disagreed in the same package.

The prose now states the standard and names the legacy spelling as legacy, which is the rule everywhere else in this spec: the standard is what is offered, compatibility is what is kept.

Reported while measuring the published cut.

0.6.2 - 2026-08-08 — a topology may come from the server #

networkGraph.nodes / edges are typed array<object> | binding, matching every other data widget in the family (heatmap.data, dataTable.rows, kanban.columns). The runtime already resolved a bound value there; the property table said literal-only, so an author reading the contract wrote the topology into the document by hand — on a platform whose whole shape is "the server draws the dashboard", that was the one widget that could not be fed.

Schema only: the generated widgets_schema.g.dart widens, nothing narrows, and every document that validated before still validates.

Raised by a reader who took the property table first and asked whether the gap was intent or omission rather than filing it as a defect.

0.6.1 - 2026-08-07 — BoxSpacing, and one definition deliberately parked #

BoxSpacingbox.margin was declared as a bare EdgeInsets, so the M3 spacing token the widget has resolved since runtime 0.4.4 was rejected at authoring time while padding accepted it. One type now covers both slots: the token, the {token} object form, and every EdgeInsets spelling.

The string branch stays open. "16px" is not a token and resolves to no inset, so catching it here would be better than catching it on screen — but box.padding has admitted any string since 1.4, and a runtime validates documents at load, so tightening the pattern would stop an already-published bundle from opening. The runtime reports the unresolved value instead.

Differential against the published registry: 20 value shapes × 2 slots, 0 narrowed, 7 widened, 33 identical. No bundle that opens today stops.

ValidationConfig is written and parked, not landed. textInput.validation emits unconstrained because the type is referenced and undefined — so defining it constrains a slot that accepted anything, and every published bundle carrying a validation block the definition did not admit would stop opening. The finished definition sits at configs/widget/_ValidationConfig.yaml (the _ prefix keeps codegen off it) for a release allowed to break bundles. The runtime half of that work needs no registry change and shipped separately.

This leaves the 27 named types requested against 1.4.1 at 26 landed, 1 parked.

0.6.0 - 2026-08-05 — the registry declares what the runtime honours (spec 1.4.1) #

The embedded schema is regenerated from spec 1.4.1. Three things changed in it.

330 properties across 80 widgets were promoted. They were read by the runtime and named nowhere, so an author could not know they existed, an editor could not offer them, and a validator was right to reject them. Each was judged in order: a variant spelling of a declared property stays out (§17.3.2 governs those), a name that breaks §17.1 is corrected rather than declared, a duplicate of something the widget already has stays out, and what remains must actually be applied by the factory. 15 alias spellings and 6 semantic duplicates were rejected on those grounds and are recorded in the spec's changelog.

Four narrowings — this is why the release is a minor. A document that validated before can now be rejected:

  • linear.distribution declares spaceBetween / spaceAround / spaceEvenly only. The kebab spellings left the canonical surface (§17.3.1a was rewritten: legacy values are no longer carried in the enum, which had made the naming rule unenforceable).
  • qrCode.errorCorrection declares low / medium / quartile / high; the QR standard's L/M/Q/H are runtime-only.
  • otpInput.autoSubmit is gone; onComplete is the declared name.
  • Option objects require value. Without it the runtime falls back to an empty string, so two entries collide and selecting one selects both. Measured first: 278 object-form options in the document corpus, none missing it.

Named types are defined. EdgeInsets existed under no name at all — it was expanded inline at every use, so a consumer resolving types by name could not check a padding or margin slot, and the emptiness looked like a pass. It is a primitive now, with a binding branch per edge ({left: "{{w}}", top: 8} is the shape documents write). Fifteen item shapes (Option, NavItem, Column, Tab, Segment, …) gained definitions too; they declare the keys the runtime reads and keep accepting further ones.

Also in this cut — Color is checked wherever a color is taken #

The primitive was written and then not used. 0.5.1 fixed Color itself — the CSS-name branch had an inline (?i:) flag that ECMA-262 does not have, so it constrained nothing and tomato validated. That fix reached 17 of the 55 slots that take a color. The other 38 were declared as a bare {"type": "string"}, so the same document that was rejected on text.color passed on box.decoration.color, avatar.backgroundColor, divider.color, headerBar.backgroundColor, markdown.linkColor, every NavigationStyle color, and the rest. All 55 reference the primitive now, including the three that carry colors inside another shape — Gradient.colors (whose own description had said "plus Gradient stops" while the items stayed open strings), BackgroundImage.colorFilter.color, and heatmap.colorRange, which had no schema at all.

rgb() / rgba() are accepted. §5.3.4 rates functional notation SHOULD and the theme parser had always read it, but the primitive had no branch for it — so a theme written the way the spec describes failed validation. The prose and the primitive are one set again: §5.3.4 now lists all five spellings with their ratings, names the ten basic colors it had only alluded to, and states that no other CSS keyword is a color here.

Measured before landing: 6,912 documents, 8,008 widget instances carrying a color. Two values fail that did not before, both signature.penColor: "textOnSurface" in a 2026-04 backup tree — a slot name that does not exist (onSurface does), which is exactly what the narrowing is for.

0.5.1 - 2026-08-03 — the schema now checks what it always declared #

isMcpUiDslWidgetType / mcpUiDslWidgetTypes are exported. A host that registers extension widgets needs to tell its own additions apart from the spec's set; without that distinction a validator ends up calling a host's own widget a malformed document.

Color accepted every string. Its CSS-name branch used an inline (?i:) flag, which ECMA-262 — the regex dialect JSON Schema uses — does not have, so the pattern was not a valid regex and the branch constrained nothing. color: "tomato" validated and then drew nothing, which is worse than being rejected. Now spelled as a character class per letter, and pinned by test/schema/color_primitive_test.dart, which checks both directions: every spelling parseColor resolves is accepted, and nothing else is.

dragTarget.builder is Required=yes in §2.10.4 and was optional in the registry, so the runtime threw on a document the schema had accepted.

Patch, deliberately. The 1.4 cut already announced that the schema narrows; that is what made 0.5.0 a minor. This does not narrow it a second time — it applies that same cut to the slots it had missed. A second floor bump would make every consumer migrate twice for one change.

X[] is not a notation the generator parses, and 51 property slots across 45 widgets used itlinear, stack and form among them. Those slots emitted a description and no constraint, so children: "hello" validated. The registry had been mixing two notations (22 slots on array<X>, checked; 51 on X[], not) and the emitted schema looks the same either way. Normalized to array<X>; those slots now require an array of the declared element type.

Once children were actually checked, a class of contract disagreements surfaced underneath — places where a document could be written per the prose and rejected by the schema, or accepted by the schema and dropped by the runtime. §17.3.1a already settles which way those go: a value the runtime accepts and the schema rejects is a contract disagreeing with itself.

  • Color is a primitive now, and accepts what the runtime accepts. It had been #RRGGBB only. The runtime also takes all 40 Material 3 scheme slots (primary, onSurfaceVariant, error, …) — the only spelling that follows light/dark mode, and the one the theme chapter tells authors to use — plus ten CSS names and 3-digit hex. Every color property was rejecting the adaptive form.
  • Alignment listed only the directional names; topLeftbottomRight are registered aliases the runtime resolves.
  • BoxShadow required offset: {dx, dy} and rejected the flat offsetX / offsetY pair the resolver reads, along with blur / spread.
  • Aliases the factories read and the registry never declared: markdown.textcontent, lottieAnimation.srcsource, and boxconstrained.
  • dataTable.rows and fileExplorer.items take a literal array; both were declared binding only. codeEditor.code was required even though binding alone supplies the content.
  • graph.data and markdown.text were truncated by the drafting tool and adopted verbatim — the union's | binding had spilled into default: and the required column into description:, so both declared that the property does not accept a binding. Eleven more type strings carried markdown backticks the generator emits verbatim.
  • box.width / height are Dimension: the runtime accepts {value, unit}, so the registry was the narrow side.
  • lazy was defined twice and the shorter copy won, so the schema carried only childcontent, trigger, onLoad and onError were absent despite being documented. Restored under its registered Utility category.

Six action types appeared when the generator stopped transcribing §17.2.2 and started reading it: client.storage.set / .get / .remove and client.notification, all documented in §4.12 with examples, plus identity.promote / identity.release, which nothing had reported because no document under test used them. The generator now also cross-checks the register against the set it used to emit, so a type disappearing from §17.2.2 is a warning rather than a document rejected weeks later.

0.5.0 - 2026-08-03 — Asset reference axis, 23 widgets, prose enums (spec 1.4) #

The embedded schema constant is regenerated from spec 1.4 after the largest vocabulary cut since the Composition Profile.

Changed #

  • README states 1.4 rather than 1.3, and its example compiles: it called ThemeDefinition.lightFromSeed (no such method — defaultLight(seedHex:)) and constructed a UIDefinition that does not exist.

Changed — narrowing, which is why this is a minor rather than a patch #

  • AssetRef slots reject a bare string carrying no scheme. image.src (and its source / backgroundImage aliases), avatar.src and lottieAnimation.src were typed as plain strings while the prose said AssetRef; they now reference the primitive. A document whose source is absent expresses that with a binding, not "" — spec §6.12.2a.
  • icon slots take IconRef. The icon widget documented three forms while the eight other icon slots were bare strings, so a codepoint object could not be written outside icon at all. IconRef states the rule once (name · codepoint · any AssetRef) and every slot references it. A bare string carrying no known scheme is still read as a name, so the named form is unchanged.
  • Thirteen string properties declare their values as enum. They listed them in description only, so text.variant rejected a typo while button.variant accepted one. linear.distribution carries its kebab spellings in the enum as well — the runtime has accepted them since v1.0 and no document said so (spec §17.3.1a).

Every widget in this workspace was checked against both the old and the new schema before the change landed: 4,476 asset and icon widgets, zero newly invalid.

Added #

  • AssetRef object form{uri, origin?}, read through MCP resources/read. No new scheme was minted for "an asset the server holds": MCP already reads an arbitrary resource uri, and Origin already says which server. The scheme pattern also opens from a closed enumeration to any RFC 3986 scheme, matching the openness Origin was written with.
  • 23 widget definitions. Core: fileInput multiSelect combobox otpInput dateTimePicker accordion popover menu contextMenu breadcrumb pagination link. Advanced: qrCode barcode pdfViewer diffViewer richTextEditor splitter resizable kanban gantt spreadsheet. Client: voiceInput.
  • 20 widget aliases (§17.3.1) and 21 properties on existing widgets.
  • navigation.openUrl — Core had no way out of the application.

0.4.3 - 2026-07-28 — Composition Profile in the embedded schemas (spec 1.4) #

Added — entry & identity value types (spec 1.4 §8.9) #

  • EntryContext, EntryIssuer, EntryNotice, IdentityContext, IdentityState, IdentitySubjectKind — how a definition was reached and who is looking at it. They live here, with the other spec value types, so authoring tools, validators and non-runtime consumers can name them without depending on the Flutter runtime; the runtime re-exports them and owns the behaviour (session, binding resolution, launch route).
  • IdentityPromotion / PromotionOutcomepromoted · declined · unavailable · failed. A host returning "no identity" for all three would leave a document unable to tell "you declined, try again" from "this host cannot sign you in", which is a distinction every established credential API preserves.
  • ActionTypes.identityPromote / identityRelease, a v14Types list, and isIdentityAction. This registry mirrors spec §17.2.2 — adding the actions to the runtime without adding them here would leave the canonical name list disagreeing with the spec it claims to mirror.

EntryNotice.fromWire folds an unrecognised notice kind onto advisory rather than dropping it, so a resolver newer than the runtime never loses a message.

Fixed #

  • ApplicationDefinition.routes was typed Map<String, String>, and fromConfig cast every value with as String. Since v1.4 a route target may be a DefinitionSource object naming another origin, so an application with a composed route threw during parsing. Routes now keep their declared shape. The same narrowing existed on the runtime side and is fixed there too.

Changed #

  • app/page/theme schemas re-versioned to 1.4. The 1.4 spec tree was seeded from 1.3 and these three kept 1.3 $ids, titles and cross-references, while only the widget schema had moved — so the machine-readable half of the release described the previous version. configs_codegen was pinned to 1.3 independently of spec_codegen's --spec-version; it now carries a _specVersion constant that moves with it.
  • RouteValue widened to a DefinitionSource ($defs/Origin added). The 1.4 prose widened routes in §1.2.1 but the config that generates the schema was never updated, so a validator would have rejected a valid composed route.

Changed — widgets schema #

  • widgets_schema.g.dart regenerated — the embedded widgets.schema.json now carries the view widget (utility category, Composition profile, since: v1.4) with its source / props / fallback / loading / onError / theme properties. Sourced from specs/mcp_ui_dsl/spec/1.4/widgets/utility/view.yaml and emitted by tools/spec_codegen, whose default --spec-version moved to 1.4 in the same change.
  • Additive: every pre-existing widget definition is byte-identical, so bundles that never use view are unaffected. A runtime that does not implement the Composition Profile treats view as an unknown widget type (error placeholder, no crash) per spec §18.7.3.

0.4.2 - 2026-07-19 — client.mcpStream channel type in the embedded page schema (spec 1.3) #

Changed #

  • page_schema.g.dart regenerated — the ChannelDefinition.type enumeration now lists client.mcpStream alongside the existing five channel types (client.watchFile, client.watchDirectory, client.systemMonitor, client.poll, client.websocket). Sourced from specs/mcp_ui_dsl/spec/1.3/configs/page/ChannelDefinition.yaml and embedded by the codegen. Additive and version-neutral: type stays an open string, so bundles using the prior five types are unaffected, and the major.minor DSL-version gate (MCPUIDSLVersion) is unchanged.
  • channel_definition.dart dartdoc lists the new type. First consumer: the client.mcpStream runtime channel (flutter_mcp_ui_runtime) — the first channel that carries an MCP-server-pushed live stream.
  • mcp_bundle floor raised ^0.4.0 → ^0.4.8 (floors-at-latest on cut; no new symbol used).

0.4.1 - 2026-05-23 — common widget property fanout (spec 1.3.4) + template validate fix + mcp_bundle 0.4.0 cascade #

Changed #

  • widgets_schema.g.dart regenerated — every widget def in the embedded widgets.schema.json now admits the common click: Action and tooltip: string properties (spec 1.3.4 §2.2). Sourced from specs/mcp_ui_dsl/spec/1.3/widgets/_common.yaml and merged by the codegen into each widget's effective property set; a widget-declared same-named property still wins. Additive — bundles that omit click / tooltip are unaffected.
  • mcp_bundle caret bumped from ^0.3.0 to ^0.4.0. The downstream bundle package switched its UiSection.pages representation from a list to a map (Map<String, PageDefinition>) to align with mcp_ui_dsl 1.3 app.schema.json. flutter_mcp_ui_core does not call that field directly, so the only consumer change here is the caret bump; consumers of this package should bump to ^0.4.1.
  • theme_schema.g.dart description regenerated to English-only (drift removed from the upstream theme.schema.json).

Fixed #

  • TemplateDefinition.validate now skips declared-type checks when the supplied argument is a binding expression ("{{...}}"). Previously a template param declared type: boolean rejected every expression-bound argument (always a String at validate time), causing use invocations to fall through templateRegistry.resolve and surface the runtime's Template not found: placeholder. Spec §9.3.1 mandates only required / default / enum / validator — strict type rejection is not required and expressions must be exempt regardless. Non-expression arguments still take the type path unchanged. Regression: test/models/tc_template_definition_test.dart (12/12).

0.4.0 - 2026-05-03 - Spec ↔ implementation alignment (1.3.3) #

  • App / page / theme JSON schema mirrored as generated Dart constants alongside the existing widgets schema.
  • ApplicationDefinition typed i18n fields, TemplateLibrary integrity, ColorScheme spec-spelling acceptance — all backward compatible.

0.3.2 - 2026-05-02 - M3 token shorthand + ResponsiveValue schema #

Schema additions to support widget-side consumption of the M3 token domains declared in 0.3.0. Backward-compatible — existing bundles continue to validate.

  • M3 token shorthand on text.variant / box.padding / card.shape / card.elevation / button.elevation / icon.size / icon.sizeToken.
  • $defs.ResponsiveValue formalised for per-form-factor property overrides.
  • 14_Responsive_Events.md rewritten on M3 5-class (compact / medium / expanded / large / extraLarge + embedded); xs/sm/md/lg/xl labels removed.
  • {{runtime.breakpoint}} renamed to {{runtime.formFactor}}.

0.3.1 - 2026-04-30 - TemplateDefinition spec alignment #

Changed (breaking — pre-launch spec alignment) #

  • TemplateDefinition widget tree wrapper field renamed bodycontent to align with MCP UI DSL 1.3 §9.2.2 (canonical key per specs/mcp_ui_dsl/spec/1.3/09_Templates.md). params field name retained — it is canonical at both the definition site and the use widget invocation site, keeping the API symmetric. Previous wire format (body) is removed; bundles must emit content.

0.3.0 - 2026-04-28 - MCP UI DSL 1.3 (Material 3 + DTCG) #

Changed (breaking) #

  • ThemeDefinition rewritten to the canonical 14-token-domain spec (color, typography, spacing, shape, elevation, motion, density, breakpoints, border, opacity, focus ring, z-index, components) with optional light/dark mode overrides. Replaces the 1.2 5-section ThemeConfig (no alias).
  • Color — Material 3 28-role plus 6 semantic roles, surface tonal scale (surfaceContainerLowest..Highest, surfaceBright/Dim). Deprecated background / surfaceVariant / textOn* names removed; inverseOnSurface renamed to onInverseSurface.
  • Typography — M3 15-role (display/headline/title/body/label × L/M/S). Legacy h1h6, subtitle1/2, body1/2, caption, button, overline removed.
  • Spacing — 9-step 8pt grid (xxs/xs/sm/md/lg/xl/2xl/3xl/4xl) plus 4 layout aliases.
  • Shape — M3 7-family with ShapeCorner.uniform / perCorner (RTL-aware).
  • Elevation — 6-level with shadow + optional surface tint, tonal fallback.
  • License changed from Apache-2.0 to MIT.

Added #

  • HCT seed palettesSeedPalette.lightFromSeed / darkFromSeed derive a 28-role palette via material_color_utilities.
  • DTCG codecThemeDefinition.toDtcg() / fromDtcg() round-trip the entire theme through W3C Design Tokens Community Group format. Compatible with Tokens Studio, Style Dictionary, Claude Design exports.
  • M3 standard state-layer opacities (hover 0.08, focus 0.12, pressed 0.16, disabled 0.38).
  • New dependency: mcp_bundle ^0.3.0.

0.2.3 #

  • Bug fixes

0.2.2 #

0.2.1 #

Bug Fixes #

  • Fixed ThemeConfig color keys to match MCP UI DSL v1.0 specification (textOnPrimary instead of onPrimary)
  • Implemented comprehensive theme validation in UIValidator
  • Added color format validation for #RRGGBB and #AARRGGBB formats
  • Fixed theme validation to check all 10 required colors (5 background + 5 text colors)
  • Added validation for theme mode (light, dark, system)
  • Added typography, spacing, borderRadius, and elevation validation
  • Fixed nested theme validation path issues
  • Removed UIDefinition model that didn't follow MCP UI DSL spec
  • Updated UIValidator to validate ApplicationConfig and PageConfig instead of UIDefinition

0.2.0 #

Refactoring #

  • Major internal refactoring for improved maintainability
  • Enhanced code organization and structure
  • Improved type safety and validation
  • Better separation of concerns

0.1.0 #

Initial Release #

  • Core models for UI definitions (UIDefinition, WidgetConfig, ActionConfig)
  • Constants for 77+ supported widget types across 9 categories
  • Comprehensive validation framework with UIValidator
  • Type-safe property key constants
  • Utility functions for JSON manipulation and type conversion
  • Property helpers for style extraction and validation
  • DSL version management (v1.0.0)
  • Structured exception hierarchy for error handling
  • Full support for MCP UI DSL v1.0 specification
3
likes
110
points
210
downloads

Documentation

API reference

Publisher

verified publishermakemind.dev

Weekly Downloads

Core models, constants, and utilities for Flutter MCP UI system. Shared foundation for renderer and generator packages.

Homepage
Repository (GitHub)
View/report issues

Topics

#ui #json #mcp #flutter #widget

License

MIT (license)

Dependencies

collection, flutter, json_schema, material_color_utilities, mcp_bundle, meta

More

Packages that depend on flutter_mcp_ui_core