Agent SDK
@rozenite/agent-sdk is the programmatic version of rozenite agent for Node.js and TypeScript scripts. Use it when you want to write a script, automation, or agent runtime that talks to a running app through Rozenite directly from code.
Before you start
Section titled “Before you start”Make sure:
- Node.js 20 or newer
- your app is running in development mode
- Metro is running and reachable
- at least one target is connected
Install
Section titled “Install”Install the SDK as a dependency:
npm install @rozenite/agent-sdkyarn add @rozenite/agent-sdkpnpm add @rozenite/agent-sdkbun add @rozenite/agent-sdkThe happy path
Section titled “The happy path”Most scripts use the same flow:
- Create a client with
createAgentClient(). - Open a short-lived session with
client.withSession(...). - Inspect the available domains and tools.
- Call the tool you need.
Your first script
Section titled “Your first script”Start with a script that opens a session and lists the domains currently available on the device:
import { createAgentClient } from '@rozenite/agent-sdk';
async function inspectApp() { const client = createAgentClient();
return client.withSession(async (session) => { const domains = await session.domains.list();
return { sessionId: session.id, domains: domains.map((domain) => domain.id), }; });}
inspectApp().then(console.log).catch(console.error);withSession(...) opens the session and closes it automatically when your callback finishes.
The next step is to inspect one domain more closely and then call one of its tools.
Inspecting domains and tools
Section titled “Inspecting domains and tools”Inside a session, you can use these helpers:
session.domains.list()to see which domains are available on the connected appsession.tools.list({ domain })to see the tools inside one domainsession.tools.getSchema({ domain, tool })to inspect a tool’s input schema before calling it
For example, you can inspect the network domain like this:
import { createAgentClient } from '@rozenite/agent-sdk';
async function inspectNetworkTools() { const client = createAgentClient();
return client.withSession(async (session) => { const tools = await session.tools.list({ domain: 'network' }); const schema = await session.tools.getSchema({ domain: 'network', tool: 'listRequests', });
return { toolNames: tools.map((tool) => tool.shortName), listRequestsInput: schema.inputSchema, }; });}Once you know what you want to call, use session.tools.call(...).
Calling tools
Section titled “Calling tools”There are two common ways to call a tool.
Call by name
Section titled “Call by name”Use this form when you already know the domain and tool name, or when you just looked them up with session.tools.list(...).
If you want a typed result, pass type arguments to session.tools.call(...).
const requests = await session.tools.call<{ limit: number }, { items: Array<{ id: string }> }>({ domain: 'network', tool: 'listRequests', args: { limit: 20 },});If you do not pass type arguments, the result is unknown.
Typed calls with plugin SDKs
Section titled “Typed calls with plugin SDKs”Official agent-enabled plugins publish ready-made typed tool descriptors under ./sdk. Use those when you want the plugin package to provide the tool name, argument type, and result type for you.
Today that includes:
@rozenite/controls-plugin/sdk@rozenite/file-system-plugin/sdk@rozenite/network-activity-plugin/sdk@rozenite/react-navigation-plugin/sdk@rozenite/redux-devtools-plugin/sdk@rozenite/storage-plugin/sdk@rozenite/tanstack-query-plugin/sdk
import { createAgentClient } from '@rozenite/agent-sdk';import { storageTools } from '@rozenite/storage-plugin/sdk';
async function readUsernameFromStorage() { const client = createAgentClient();
return client.withSession(async (session) => { const result = await session.tools.call(storageTools.readEntry, { adapterId: 'mmkv', storageId: 'user-storage', key: 'username', });
return result; });}Pagination
Section titled “Pagination”Some tools return paged results. The SDK makes one tool call and returns the plugin’s page and cursor unchanged. To fetch another page, pass the returned cursor explicitly in the next call.
type RequestsPage = { items: Array<{ id: string }>; page: { limit: number; hasMore: boolean; nextCursor?: string };};
const firstPage = await session.tools.call<{ limit: number; cursor?: string }, RequestsPage>({ domain: 'network', tool: 'listRequests', args: { limit: 50 },});
const secondPage = firstPage.page.nextCursor ? await session.tools.call<{ limit: number; cursor?: string }, RequestsPage>({ domain: 'network', tool: 'listRequests', args: { limit: 50, cursor: firstPage.page.nextCursor }, }) : undefined;Choosing a target
Section titled “Choosing a target”If only one target is connected, withSession(...) is usually enough.
If more than one target is connected, list them first and pass deviceId when opening the session:
import { createAgentClient } from '@rozenite/agent-sdk';
async function inspectSpecificDevice() { const client = createAgentClient(); const targets = await client.targets.list();
return client.withSession({ deviceId: targets[0].id }, async (session) => { return { sessionId: session.id, deviceId: session.info.deviceId, }; });}Managing sessions
Section titled “Managing sessions”- Use
withSession(...)for short scripts and one-off tasks. It handles setup and cleanup for you. - Use
openSession()when the session needs to stay open across multiple independent steps or function boundaries. - Use
attachSession(sessionId)when you need to reconnect to an already-existing session instead of creating a new one.
When you do need manual control, remember to stop the session yourself:
import { createAgentClient } from '@rozenite/agent-sdk';
async function inspectRozeniteManually() { const client = createAgentClient(); const session = await client.openSession();
try { const domains = await session.domains.list();
return { session: session.info, domains, }; } finally { await session.stop(); }}If you already have a sessionId, you can reconnect like this:
import { createAgentClient } from '@rozenite/agent-sdk';
async function reconnectToSession(sessionId: string) { const client = createAgentClient(); const session = await client.attachSession(sessionId);
return { sessionId: session.id, deviceId: session.info.deviceId, };}Next steps
Section titled “Next steps”- Rozenite for Agents – how agents use domains and tools
- Adding tools to your application – expose app-owned tools under the
appdomain - Plugin Development – general plugin structure and app-side integration