inkpal_bridge 4.1.1 copy "inkpal_bridge: ^4.1.1" to clipboard
inkpal_bridge: ^4.1.1 copied to clipboard

Let AI agents inspect, debug, and control your running Flutter app — read widgets, tap, screenshot, audit. Zero deps. Debug-only. Free for everyone.

inkpal_bridge #

Let your AI inspect, debug, and control your running Flutter app.

Works with Claude Code, Cursor, Windsurf, Codex CLI, and Copilot in VS Code.

pub package pub points

60-second setup #

# pubspec.yaml
dependencies:
  inkpal_bridge: ^4.1.0
// lib/main.dart
import 'package:inkpal_bridge/inkpal_bridge.dart';

void main() => inkpalRunApp(const MyApp());
flutter run

That's it. The bridge starts itself and prints:

┌──────────────────────────────────────────────────────────────┐
│  InkPal Bridge active                                        │
│  WebSocket: ws://localhost:8765                              │
│  MCP:       http://127.0.0.1:8767/mcp                        │
│                                                              │
│  No CLI needed. Paste into your editor's .mcp.json:          │
│                                                              │
│    {"mcpServers":{"inkpal":{"transport":"http",              │
│      "url":"http://127.0.0.1:8767/mcp"}}}                    │
│                                                              │
│  Or for cloud + Figma + host CLI tools:                      │
│    npx inkpal start                                          │
│                                                              │
│  Free for everyone   ·   no API key, no signup               │
└──────────────────────────────────────────────────────────────┘

The bridge is already watching for errors, HTTP traffic, navigation events, and widget-tree changes. It runs entirely debug-only — release builds collapse inkpalRunApp to a plain runApp with zero overhead.

Connect an AI assistant #

The bridge exposes an MCP HTTP transport on http://127.0.0.1:8767/mcp directly — no Node, no npx, no CLI install of any kind.

Paste one block into your editor's MCP config:

Claude Code (.mcp.json in your project root, or ~/.claude/mcp.json):

{
  "mcpServers": {
    "inkpal": {
      "transport": "http",
      "url": "http://127.0.0.1:8767/mcp"
    }
  }
}

Cursor (~/.cursor/mcp.json), Windsurf, VS Code (Copilot), Codex CLI all accept the same shape. Restart your editor and ask:

"Audit my UI for layout issues. Tap the save button and screenshot the result."

The bridge handles ~30 tools directly: every gesture, screenshot, assertion, wait-for, observe(), accessibility audit, state-seed extension, log query, and runtime-error capture.

Need cloud + Figma + host CLI tools? #

For pattern search, Figma round-trips, flutter analyze, dart format, and the rest of the catalog, install the optional npm proxy:

npx inkpal start

It auto-registers itself with detected editors and serves the full ~150-tool surface (the bridge subset plus everything that needs external network or host-process access). The two transports coexist — your editor sees one merged tool list.

Migrating from 3.x #

No source changes required. The 3.x licenseKey: and apiUrl: parameters on inkpalRunApp / InkPalBridge.init are accepted as deprecated no-ops in 4.0 — your existing code keeps compiling, you'll see an analyzer hint, and a one-line debug log:

[InkPal] DEPRECATED: inkpalRunApp(licenseKey: ...) is ignored —
inkpal_bridge is free for everyone in 4.0. Remove the parameter.

To silence both, delete the two parameters:

// 3.x
inkpalRunApp(
  MyApp(),
  licenseKey: const String.fromEnvironment('INKPAL_LICENSE_KEY'),
  apiUrl: 'https://mcp.inkpal.ai',
);

// 4.0
inkpalRunApp(MyApp());

If you launched with flutter run --dart-define=INKPAL_LICENSE_KEY=..., drop the --dart-define — the env var is no longer read. The deprecated parameters will be removed in 5.0.

Custom widgets (walkerHooks) #

Have proprietary design-system widgets (BrandButton, GlassCard) without standard Material semantics? Teach the bridge to recognise them:

inkpalRunApp(
  const MyApp(),
  walkerHooks: InkPalWalkerHooks(
    isInteractiveWidget: (w) => w is BrandButton,
    extractTextFrom: (w) => w is BrandButton ? w.label : null,
  ),
);

The agent can then say "tap the Save button" and the bridge resolves it correctly — no need to wrap every callsite in Semantics(label:).

A working demo lives in example/lib/main.dart.

Router support #

Works with every major Flutter router.

go_router — just pass your GoRouter instance. The bridge drives navigation and tracks the current route automatically, including imperative context.push(...), with no NavigatorObserver wiring:

final router = GoRouter(routes: [...]);

inkpalRunApp(
  MyApp(router: router),
  router: router, // drives navigation + auto-tracks the route for observe()
);

Other routers — pass onNavigateToRoute so the bridge can drive named navigation:

// GetX
onNavigateToRoute: (route) async => Get.toNamed(route),

// Beamer
onNavigateToRoute: (route) async => beamerDelegate.beamToNamed(route),

Standard Navigator works without any callback.

App-state context #

Expose your app's runtime state so the agent has more to reason about:

inkpalRunApp(
  const MyApp(),
  globalStateProvider: () async => {
    'user': {'plan': currentUser.plan},
    'cart': {'items': cart.length, 'total': cart.total},
  },
);

App extensions (seed state + custom ops) #

Expose app-specific operations the agent can invoke directly — reset/seed data, flip a feature flag, jump onboarding — without shipping a new bridge version. Register handlers and the MCP surfaces them through inkpal_list_app_extensions / inkpal_call_app_extension:

InkPalAppExtensions.register(
  name: 'seed',
  description: 'Wipe and reseed the sample dataset.',
  handler: (params) async {
    await db.reseed();
    return {'reseeded': true};
  },
);

The agent can now set up any starting state in one call instead of clicking through the UI — ideal for deterministic, repeatable runs.

Architecture #

Your AI assistant   ⇄   inkpal_bridge   ⇄   your running Flutter app

The bridge runs entirely in debug mode. In release builds, inkpalRunApp collapses to a direct runApp call — zero overhead, zero memory allocation, no socket, no extension registration. Your release builds ship as if the bridge wasn't there.

Privacy + security #

  • Debug-only. Release builds bypass everything.
  • Local-first. Communication binds to localhost. Nothing leaves your machine without explicit configuration.
  • Sensitive headers redacted. Authorization, Cookie, X-Api-Key, and similar patterns are stripped before any HTTP request is surfaced to the agent.
  • Open-source. MIT-licensed.

Advanced configuration #

For release-mode shipping, custom server URLs, or fine-grained control over the bridge's subsystems, use InkPalBridge.init directly:

void main() {
  InkPalBridge.init(
    serverUrl: 'ws://localhost:8765',
    appRunner: () => runApp(const MyApp()),
  );
}

See API docs for the full surface.

Support #

Issues and feature requests on GitHub.

Requirements #

  • Flutter ≥ 3.10
  • Dart ≥ 3.0
5
likes
160
points
1.15k
downloads

Documentation

API reference

Publisher

verified publisherinkpal.ai

Weekly Downloads

Let AI agents inspect, debug, and control your running Flutter app — read widgets, tap, screenshot, audit. Zero deps. Debug-only. Free for everyone.

Homepage
Repository (GitHub)
View/report issues

Topics

#mcp #ai #claude #copilot #agent

License

MIT (license)

Dependencies

flutter

More

Packages that depend on inkpal_bridge