Provider-neutral Kotlin and TypeScript SDKs for turning an existing application into an application that agents can safely use.
Applications define their own tools and UI renderers. The Kotlin runtime registers, validates, approves, and executes those tools through the custom app-agent/1 protocol. Optional UI modules let a tool pair concise model-readable output with an application-defined interface. The TypeScript client discovers and calls the same capabilities from desktop or other agent harnesses. The currently shipped transport uses ADB-forwarded loopback; authenticated remote relay transport remains a separate future adapter. Optional Android UI automation is an app-scoped fallback rather than the primary interface.
Status: experimental. The public API and wire protocol may change before
1.0.0.
Current releases: Kotlin/Maven 0.4.0; TypeScript packages are workspace source packages and are not yet published to npm.
- This is a custom application-agent protocol, not MCP.
- The packages contain no finance, commerce, weather, or other domain-specific tools.
- Every application defines its own
name,description,inputSchema, and handler. - Desktop and in-app agents can share the same mobile
ToolRuntime. - Application credentials remain inside the mobile handler and are never sent to the model.
- Approval is runtime policy, not part of the model-visible tool definition.
- An optional harness-owned UiAutomator2 companion provides app-scoped screen interaction when no semantic application tool exists.
The same application-owned capabilities can serve a desktop agent and an in-app agent. The application remains responsible for business behavior, authenticated services, and every rendered interface.
flowchart LR
desktop["Desktop agent and chat UI"] --> client["TypeScript client"]
client --> loopback["ADB-forwarded loopback"]
loopback --> runtime["Application ToolRuntime"]
inApp["In-app service agent"] --> runtime
runtime --> tools["Application-defined tools"]
tools --> services["Authenticated application services"]
tools --> frames["Optional application-defined UI frames"]
frames --> desktop
frames --> inApp
Choose only the layers an integration needs:
| Goal | Start with |
|---|---|
| Expose safe application capabilities | app-agent-runtime and application-defined ToolSpec handlers |
| Connect a desktop agent | app-agent-client and app-agent-transport-loopback |
| Return application-owned dynamic UI | app-agent-ui and, for Compose, app-agent-ui-compose |
| Automate an existing screen as a fallback | app-agent-android-ui and the UiAutomator2 companion |
| Inspect calls and approvals during development | app-agent-inspector with the release no-op counterpart |
| Path | Responsibility |
|---|---|
protocol/ |
Canonical, language-neutral app-agent/1 JSON Schema |
packages/app-agent-runtime/ |
Kotlin registry, validation, approval, and execution |
packages/app-agent-transport-loopback/ |
Kotlin loopback HTTP transport for Android/JVM and ADB |
packages/app-agent-ui/ |
Framework-neutral UI frames, navigation, and lifecycle |
packages/app-agent-ui-compose/ |
Optional Compose frame host, approval UI, and notification |
packages/app-agent-inspector/ |
Debug tool-call audit UI and foreground shake entry point |
packages/app-agent-inspector-noop/ |
API-compatible release no-op for the Inspector |
packages/app-agent-client/ |
Typed TypeScript protocol client |
packages/app-agent-android-ui/ |
Typed TypeScript Android UI fallback tools |
drivers/android-uiautomator2/ |
Optional generic instrumentation companion |
docs/sdk/ |
Architecture and integration documentation |
examples/weather-agent/ |
Android weather and desktop agent example |
examples/trading-agent/ |
Native Android UI-frame and local-order example |
data class ToolSpec(
val name: String,
val description: String,
val inputSchema: JsonObject,
)Handlers, approval policy, authentication state, transport settings, and call IDs are deliberately kept outside ToolSpec.
- Kotlin SDK
- On-device approval
- Compose approval UI
- Application-defined UI frames
- Debug audit inspector
- TypeScript client
- TypeScript package architecture
- Architecture
- Tool authoring
- Android integration
- Approval testing
- Approval troubleshooting
- Protocol
- Android UI automation fallback
- Android UI package
- Distribution
- Weather agent example
- Native trading agent example
- Changelog
The repository includes a GitHub Packages publishing workflow. Pushing an SDK version tag publishes the Kotlin runtime, loopback transport, UI contracts, approval UI, and debug Inspector pair:
io.github.pumpkinredbean:app-agent-runtime:<version>
io.github.pumpkinredbean:app-agent-transport-loopback:<version>
io.github.pumpkinredbean:app-agent-ui:<version>
io.github.pumpkinredbean:app-agent-ui-compose:<version>
io.github.pumpkinredbean:app-agent-inspector:<version>
io.github.pumpkinredbean:app-agent-inspector-noop:<version>
The npm workspaces build publication-ready ESM packages with declarations, but the repository does not currently publish them to npm:
@pumpkinredbean/app-agent-client
@pumpkinredbean/app-agent-android-ui
See SDK distribution and installation for credentials, release steps, and consumer configuration.
See CONTRIBUTING.md before opening a change. Please report vulnerabilities through the process in SECURITY.md, not a public issue.
Licensed under the Apache License 2.0.