Appduct lets a terminal, a test runner, or an AI agent call functions inside your running iOS, Android, React Native or web app. Appduct calls these functions tools. Only the tools you register are reachable.
- E2E tests skip the setup. Instead of tapping through login, onboarding and an empty cart, a test calls
log_inorseed_cartand starts at the screen it's testing. - Agents can drive your app. Over MCP or the CLI, an agent can flip a feature flag, open a screen, or read some state through your tools.
- No hidden debug UI. There's no secret gesture or admin panel for someone to find.
- Release builds leave it out. By default Appduct is only in debug builds. You can opt in for internal builds such as TestFlight; see Build variants.
- You add the Appduct library to your app and register tools. Each tool has a name, a description, an input schema and a handler.
- You install the
appductCLI on your computer. To connect, the CLI gives your app a link, either opened on the device for you or scanned as a QR code. The app then connects back to your computer over an encrypted connection. The connection survives reloads, backgrounding and dropped Wi-Fi. - You call tools from the terminal, a test, or an agent.
Register a tool in your app:
iOS (Swift)
import AppductCore
try Appduct.shared.register(
name: "seed_cart",
description: "Fill the cart with test items.",
inputSchema: ["type": "object", "properties": ["items": ["type": "number"]], "required": ["items"]]
) { args in
["added": (args["items"] as? NSNumber)?.intValue ?? 0]
}Android (Kotlin)
import com.callstack.appduct.Appduct
import org.json.JSONObject
Appduct.register(
name = "seed_cart",
description = "Fill the cart with test items.",
inputSchema = JSONObject("""{"type":"object","properties":{"items":{"type":"number"}},"required":["items"]}"""),
) { args ->
JSONObject().put("added", args.optInt("items"))
}React Native
import { useAppductTool } from "@appduct/react-native";
import { z } from "zod";
useAppductTool({
name: "seed_cart",
description: "Fill the cart with test items.",
inputSchema: z.object({ items: z.number() }),
handler: async ({ items }) => ({ added: items }),
});Call it from your terminal:
appduct tools call seed_cart --input '{"items":3}'-
Install the CLI:
npm install -g appduct
-
Add Appduct to your app:
- iOS, with Swift Package Manager or CocoaPods
- Android, from Maven Central
- React Native. You need a development build; Expo Go doesn't work.
- Web, for any framework or plain JavaScript
To try it before touching your own app, run a playground app: iOS, Android or React Native.
- Documentation site: guides and reference for every platform
- CLI guide: connect to a device, list and call tools
- Use Appduct with an agent: MCP config and the agent skill
- Call tools from tests: the
appduct/clientAPI - Registering tools: schemas, long-running tools and events
- Build variants: which builds include Appduct, including web production bundles
- Security: what it protects against, trust and key rotation
- Packages and platform support
appduct is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. Callstack is a group of React and React Native geeks, contact us at hello@callstack.com if you need any help with these or just want to say hi!
Like the project? ⚛️ Join the team who does amazing stuff for clients and drives React Native Open Source! 🔥
