in_app_mcp 1.3.0 copy "in_app_mcp: ^1.3.0" to clipboard
in_app_mcp: ^1.3.0 copied to clipboard

Policy-gated tool runtime for in-app LLM/agent tools. Per-tool auto/confirm/deny, typed contracts, structured results.

1.3.0 #

  • User input requests. New UserInputRequest model + ToolResult.requiresInput(...) factory give a handler a first-class way to pause mid-call and ask the user for structured data (pick an option, upload photos, confirm a location, fill a form) before resuming. The host app reads result.pendingInputs, renders whatever widget matches each request's kind, merges the collected values back into ToolCall.arguments, and re-invokes handleToolCall.
  • Motivating pattern: chat-assist UX where the LLM drives the conversation but needs the user to supply domain-specific input (location autocomplete, photo picker, typed form) that can't be expressed as plain text. Previously each app rolled its own side channel; now it flows through the normal tool-call round-trip and audit ledger.
  • New error code ToolErrorCode.requiresUserInput ('requires_user_input') is carried on the result's code so downstream consumers can branch without inspecting pendingInputs directly. A new ToolResult.requiresUserInput getter returns true when the list is non-empty.
  • Fully additive — existing 1.2.x consumers see no change. Handlers that want to return requiresInput must declare the pending arguments as non-required in their ToolDefinition (required arguments are still enforced by the registry before the handler runs).

Example app #

  • New book_trip demo tool (example/lib/agent_tools/book_trip_tool.dart) — every argument (destination, date, tripType, passengers) is optional, so the handler runs, spots what's missing, and returns ToolResult.requiresInput(...) with one request per missing field (text, single_choice, number). Prompt the agent with "Book a trip" to trigger it.
  • ChatDemoScreen gained a pending-input form inside the inline tool-call card: renders a TextField / DropdownButtonFormField / numeric field per UserInputRequest.kind, adds an "Awaiting input" status + "Submit inputs" button, and re-invokes handleToolCall with the merged arguments.
  • Mock adapter emits an empty book_trip call when the prompt mentions book / trip / travel / flight — exercises the full loop offline.
  • Gemma adapter sees the tool too: the generated schema lists all four arguments as optional, so the model is free to fill whatever it can infer from the prompt and leave the rest for the handler to request. Once a Gemma model is downloaded via Settings, the same prompt drives the same UI flow.
  • New unit tests (example/test/book_trip_tool_test.dart) cover the handler's partial / full outcomes; a new widget test (example/test/widget_test.dart) drives the end-to-end UI flow: prompt → inline card → Run → inputs form → fill → Submit → success.

1.2.0 #

  • Interceptors. New InvocationInterceptor abstract class with four optional hooks — onResolvePolicy, beforeExecute, afterExecute, onAudit — lets host apps observe or modify the invocation pipeline without replacing a whole PolicyStore / GrantStore / AuditLedger. Register via the new interceptors: parameter on the InAppMcp constructor.
  • Canonical use cases: rate limiting (beforeExecute returns rate_limited), remote-config policy overrides (onResolvePolicy), PII redaction (afterExecute), telemetry fan-out to Sentry / Datadog (onAudit).
  • Chain semantics: onResolvePolicy and afterExecute are chain-through (each interceptor sees the upstream's output); beforeExecute is first-non-null-wins (vetoing short-circuits the rest); onAudit is fan-out with errors swallowed so telemetry failures never break an invocation. Exceptions from the modifying hooks propagate and fail the call as a handler exception would.
  • Fully additive — existing 1.1.x consumers see no change.

1.1.0 #

Consent Lifecycle — four composable features that turn in_app_mcp from a policy gate into a full preview → confirm → execute → audit → undo trust loop for in-app AI tool calls.

Added #

  • Ephemeral grants (EphemeralGrant + GrantStore + InMemoryGrantStore). One-use, time-bounded, or session-scoped policy upgrades. New facade methods: grantOnce / grantFor / grantUntilCleared / revokeGrant / revokeAllGrants / listActiveGrants / peekGrant.
  • Audit ledger (AuditLedger + AuditEntry + InMemoryAuditLedger). Every call outcome (successes, policy denials, confirmation short-circuits, missing tools) records one entry. changes stream for live UI. Exposed via InAppMcp.auditLedger.
  • Preview hook (Preview + PreviewWarning + ToolPreviewer typedef). Side-effect-free function registered alongside a tool's handler; runtime exposes InAppMcp.previewToolCall. New @McpToolPreview annotation + generator support in in_app_mcp_gen.
  • Undo hook (ToolUndoer typedef + InAppMcp.undoFromLedger). Reverses a prior successful call by running the tool's registered undoer and marking the ledger entry undone. New @McpToolUndo annotation + generator support. Five new ToolErrorCodes: auditDisabled, entryNotFound, alreadyUndone, nothingToUndo, undoNotSupported.
  • PolicyEngine gained peek / peekDetailed (non-consuming), decideDetailed, ResolvedPolicy, PolicySource.
  • InAppMcp.dispose() for ledger teardown.

Example app #

  • Inline tool-call card now shows a preview section with warnings, a grant submenu ("Run + allow 5 min / for session"), and a per-entry Undo button after success.
  • New audit timeline screen browses ledger history with per-entry undo.
  • New Active grants card in settings with individual + revoke-all controls.
  • ScheduleWeekdayAlarmTool ships a previewer ("Would schedule X at HH:MM on Mon, Tue, …") and an undoer (cancels the notifications).
  • New E2E integration test example/integration_test/consent_lifecycle_test.dart covers preview → grant → execute → audit → undo.

Changed #

  • ToolRegistry.registerTool accepts optional previewer / undoer.
  • InvocationEngine.handle records every outcome to an optional auditLedger including pre-policy and pre-execution short-circuits.
  • InAppMcp constructor adds optional grantStore, auditLedger, enableGrants, enableAudit with in-memory defaults; getPolicyDecision now peeks (non-consuming).

All changes are additive — existing consumers of 1.0.x keep working unchanged.

1.0.2 #

  • Reposition README and pub.dev description around the per-tool policy gate (the differentiator vs. mcp_server / mcp_client / dart_agent_core). No runtime changes.
  • Clarify in README that in_app_mcp is a local in-process tool runtime, not an implementation of the MCP wire protocol (JSON-RPC / stdio / SSE).
  • Refresh the "Current status" section to reflect the 5 demo tools and codegen companions shipped alongside the 1.0.x runtime.
  • Add dartdoc to the remaining default constructors (PolicyStore, InMemoryPolicyStore, ToolErrorCode, ToolRegistry) — pana dartdoc coverage rises from 94.8% to 100%.

1.0.1 #

  • Convert in_app_mcp from a Flutter plugin to a pure Flutter package. The plugin scaffolding from flutter create --template=plugin (android/, ios/, lib/in_app_mcp_method_channel.dart, lib/in_app_mcp_platform_interface.dart) was unused — lib/in_app_mcp.dart never called into it. The package now supports every platform Flutter targets out of the box.
  • Drop unused plugin_platform_interface dependency.
  • Add dartdoc comments across the public API (InAppMcp, ToolCall, ToolDefinition, ToolArgType, ToolResult, ToolErrorCode, ToolPolicy, PolicyDecision, PolicyStore, InMemoryPolicyStore, ToolRegistry, RegisteredTool, InvocationEngine). No behavioural changes.

1.0.0 #

  • Stable public API.
  • Add ToolDefinition.toJsonSchema() returning an OpenAI-style JSON schema so LLM adapters can serialise a tool definition without hand-rolling it.
  • Add InAppMcp.toolsSchemaJson() aggregating schemas for every registered tool into {"tools": [...]}.
  • Redesign the example app's inline tool-call card with per-tool icons, colour-coded status and policy chips, and a structured result view instead of raw JSON.
  • Fix gemma_adapter handling of responses where Gemma 4 E2B emits unquoted JSON object keys (e.g. {"toolName":"x","arguments":{hour:6}}). A preprocessing pass quotes bareword keys before ToolCallParser runs.
  • Ship companion packages in_app_mcp_annotations and in_app_mcp_gen for generating ToolDefinitions and typed handler adapters from annotated Dart functions.

0.0.2 #

  • Expand example app with a full-screen chat experience and dedicated settings screen.
  • Add inline tool-call proposal cards with manual Run/Cancel and per-tool policy visibility.
  • Add Gemma adapter flow with model selection, local model catalog/status management, and tool-call parsing helpers.
  • Add additional example tools (calendar, maps, email) and broaden integration/widget/parser test coverage.
  • Improve runtime validation and policy/registry behavior for stricter tool argument handling.

0.0.1 #

  • Initial release of in_app_mcp with in-app tool runtime, policy controls, registry, and method-channel scaffolding.
3
likes
160
points
266
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Policy-gated tool runtime for in-app LLM/agent tools. Per-tool auto/confirm/deny, typed contracts, structured results.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on in_app_mcp