Agent SDK
Session scoping and OAuth
Scope MCP auth and resumed conversations to the current host session, pass host identity correctly, and choose between built-in and custom auth handling.
For embedded and first-party product agents, the two most important identity inputs are:
appSessionKeyuserIdentity
Together, they tell the SDK:
- which signed-in host session the agent belongs to
- which user should be associated with same-user MCP auth
- when persisted auth or resumed conversation state should be invalidated
appSessionKey#
appSessionKey is your app's current signed-in session boundary.
Examples:
- your session id
- a stable signed-in token id
- a value that changes on logout/login
const agent = useAppAgent({
apiKey: "emcy_sk_xxxx",
agentId: "ag_xxxxx",
appSessionKey: session.id,
});Pass it so persisted MCP OAuth state and resumed conversations do not leak across session changes.
userIdentity#
userIdentity is the current signed-in host user.
userIdentity: {
subject: session.user.id,
email: session.user.email,
organizationId: session.organizationId,
displayName: session.user.name,
}Use it whenever the agent may need same-user OAuth-backed access to downstream MCP tools.
Built-in popup auth on web#
In the React package, if you do not provide onAuthRequired, the SDK uses its built-in popup auth controller.
That gives you:
popupAuthStatestartOrRetryPopupAuth()cancelPopupAuth()
This is the simplest path for web.
Custom auth handling#
If you want to own the auth UI flow yourself, provide onAuthRequired.
const agent = useAppAgent({
apiKey: "emcy_sk_xxxx",
agentId: "ag_xxxxx",
appSessionKey: session.id,
userIdentity,
onAuthRequired: async (serverUrl, authConfig) => {
const token = await openCustomAuthModal(serverUrl, authConfig);
return token;
},
});Use this when:
- you already have a native auth-session flow
- you need custom OAuth callback handling
- you need host-specific consent UI
Native platform auth helper#
If you are building outside the default web popup flow and you have a platform auth implementation, use createPlatformAuthHandler from @emcy/agent-sdk/app.
import { createPlatformAuthHandler } from "@emcy/agent-sdk/app";
const onAuthRequired = createPlatformAuthHandler({
platform,
userIdentity,
oauthCallbackUrl: "myapp://oauth/callback",
});This is especially useful for React Native or custom browser environments.
Browser platform defaults#
If serviceUrl points to localhost and you do not override them, the web experience defaults to:
http://localhost:3100/oauth/callbackhttp://localhost:3100/.well-known/oauth-client-metadata.json
That is designed to work cleanly with the local Emcy web app during development.
Resume scoping#
The App Agent layer persists conversation resume state by combining:
- agent identity
appSessionKeyconversationResumeVersion- your optional conversation namespace
That means resumed conversations are automatically dropped when they are no longer compatible or no longer belong to the current signed-in session.
Recommended production pattern#
- always pass
appSessionKey - pass
userIdentityfor same-user MCP auth - use the built-in popup flow on web unless you have a strong reason not to
- use explicit native platform auth on mobile
- test logout/login and account-switch flows, not just the happy path
