Your server authenticates the user and signs a bootstrap assertion. The browser’s SDK client obtains that assertion through a callback, establishes a public session, and exposes the agent’s current policy for your app to inspect. Keep those server and browser responsibilities separate when embedding an external agent.
The diagram shows the browser, server, agent, result, session, and error path; the integration steps below apply those boundaries to an embedded agent.
Keep trust on the server and interaction in the app
The browser is where the visitor uses your application. The server is where you authenticate that visitor and protect the credential used to sign assertions. The External Agents SDK connects to the public runtime using an externalAgentRef and a getBootstrapAssertion callback. The callback provides a signed assertion; it does not sign the assertion itself.
The setup documented in the SDK uses this client shape:
import { createExternalAgentClient } from '@agentshelf/external-agents-sdk';
const client = createExternalAgentClient({
externalAgentRef: 'ext_agent_public_12345678',
getBootstrapAssertion: async () => {
const response = await fetch('/api/agentshelf/bootstrap-assertion');
if (!response.ok) {
throw new Error('Could not obtain a bootstrap assertion');
}
return response.text();
},
});
The endpoint path is an application example from the canonical guide, not a route created by the SDK. Its server handler must authenticate the current user and mint the assertion. Do not place the signing credential in browser code or return it from the endpoint. Use the canonical getting started guide for the complete server and client setup.
Complete one integration slice
Start with one user journey, such as a signed-in person asking an internal service desk for the status of a request. Define which identity the server verifies, which external agent reference the app is configured to use, and what the user sees if the assertion endpoint or runtime is unavailable.
- Authenticate at the app boundary. The server endpoint checks the application’s normal login session before issuing an assertion for that user.
- Create the SDK client. Keep the public agent reference in app configuration and make
getBootstrapAssertioncall the authenticated server endpoint. - Establish and inspect the session. Call
ensure(), then read the current policy withgetEffectivePolicy()before displaying actions or starting a conversation. - Show only supported actions. Use the policy’s capabilities and domain tools to decide which controls to render. A UI control is not an authorization boundary; the system still has to enforce access.
- Handle the result explicitly. Stream the response into the conversation and distinguish a completed message from an error, a pending interaction, or an approval request.
Integration check (fictional service desk)
Request: A signed-in employee asks for the state of service request SR-204.
Session:ensure()establishes a session or reuses a valid stored one, then returns a publicsessionRef.
Policy: The agent exposes messaging and conversations; the app renders no unsupported controls.
Record consulted: The approved service-system record SR-204 has status “Under review.”
Result: The stream ends withmessage:completeand reports “Under review.” No record update is requested.
This completed example assumes the agent is separately configured with an approved way to look up SR-204. The SDK client does not create that business-system connection. If the feature depends on files, artifacts, or a domain tool, check its public policy before designing the interface. For the exact capability fields, continue to policy and capabilities.
Review session and error behavior
By default, the SDK stores session state in memory, so a reload loses it. A persistence adapter can retain a session, but the stored record contains the bearer session token. Choose the store based on the scripts and users that can read it, use a distinct storageKey for each embedded agent, and revoke the session when the visitor signs out.
Plan visible behavior for a denied request, an expired session, a timeout, or an interrupted stream. For the signed-reference and server-trust design, read public references and secure bootstrap; for the message lifecycle, read sessions, conversations, and artifacts.