Agent SDK
Build a first-party app agent
Use the shared App Agent layer to build a branded assistant that feels native to your product without rebuilding runtime semantics.
There are two valid ways to integrate Emcy into a product:
- Embed mode: use the standard widget for fast adoption
- First-party app agent mode: build your own branded in-product assistant using the shared App Agent model
ChecklistSquad web and mobile are examples of the second mode.
That means:
- the app owns the visual experience
- the app owns client tools and app context
- Emcy still owns the runtime, MCP auth lifecycle, turn orchestration, approvals, requests, and tool execution
When to choose a first-party app agent#
Choose this path when the assistant should feel like a core product surface instead of a generic widget.
Examples:
- a workflow app with a docked assistant
- a native mobile app with a bottom-sheet agent
- a domain-specific assistant that needs transcript, systems, and approval views integrated into the app chrome
Package roles#
Use the packages like this:
@emcy/agent-sdk- runtime, transport, auth, tool execution
@emcy/agent-sdk/react- web app binding for custom product assistants
@emcy/agent-sdk/react-native- React-Native-safe app binding for custom native assistants
@emcy/agent-sdk/app- framework-agnostic App Agent controller and shared helpers
@emcy/agent-sdk/react-embed- drop-in widget for fast web embeds
Recommended pattern#
For a first-party app agent:
- configure an agent normally
- attach MCP servers normally
- pass host identity for embedded same-user auth when needed
- define your app-specific
clientTools - define your app-specific
appContext - build the UI around
useAppAgent - render approvals, structured input requests, and connection state from SDK-owned state
React Native custom shell#
Use @emcy/agent-sdk/react-native when you want your own app-native layout.
import { useAppAgent } from "@emcy/agent-sdk/react-native";
function MyAssistantShell() {
const agent = useAppAgent({
apiKey: "emcy_sk_xxxx",
agentId: "ag_xxxxx",
serviceUrl: "https://api.emcy.ai",
appSessionKey: session.id,
userIdentity: {
subject: session.user.id,
email: session.user.email,
organizationId: session.organizationId,
},
clientTools,
appContext,
});
const toolMessages = agent.conversation.toolMessages;
const approvals = agent.approvals.pending;
const requests = agent.requests.pending;
return null;
}Web custom shell#
For web, use useAppAgent from @emcy/agent-sdk/react and build your custom layout from the App Agent state surface.
Common patterns:
- docked transcript panel
- assistant chrome inside your own sidebar or workspace
- systems sheet or tool inspector
- branded approval and request cards
- page-specific prompt entry points outside the main assistant input
What the shared App Agent layer now owns#
Do not rebuild these per app:
- resume and stale-conversation recovery
- pending-turn state
- inline feed state
- latest message and last-turn summaries
- grouped conversation and tool state
- approvals
- structured input requests
- feedback submission state
- connection attention and status labels
Those are shared platform concerns now.
What stays app-specific#
These still belong in the app:
- theme
- layout
- navigation
- scene placement
- app-specific client tools
- app-specific app context
That is the right split for a first-party app agent:
- shared runtime semantics
- shared App Agent behavior
- customized product experience
