Choose your integration
Four shapes cover every way a product adopts Configure. Pick the row that matches what you are building, then follow that one path. Each path is complete on its own: none of them is a prerequisite for another.
| You want | Path | Time |
|---|---|---|
| Users sign in to your product with Configure | SSO | 5 minutes |
| Your agent connects users itself, in the conversation | MCP | 5 minutes |
| Your own "Connect to Configure" button, then agent tool calls | SDK plus SSO | 10 minutes |
| Configure sign-in, then profile reads from your backend | SSO plus SDK | 10 minutes |
Two ideas make the table make sense:
- SSO is authentication. It signs a user in and hands your backend Configure tokens, the way Sign in with Google does. It is not part of the SDK, and you can use it without ever installing the SDK.
- The SDK and MCP are two ways to use the profile after that. The SDK is for code you write (deterministic: your backend decides when to read). MCP is for an agent to decide (the model calls the tool when it judges it needs context). Pairing them is normal: the SDK renders your UI, MCP is how your agent reads.
Every path starts with the same five credentials, once:
bash
CONFIGURE_API_KEY=sk_...
CONFIGURE_PUBLISHABLE_KEY=pk_...
CONFIGURE_AGENT=your-agent
CONFIGURE_OAUTH_CLIENT_ID=oc_...
CONFIGURE_OAUTH_CLIENT_SECRET=ocs_...Sign in at configure.dev/login and the keys screen shows all five, including the callback field that mints the OAuth client. Or run npx configure setup --users in your project and it writes them to .env, then npx configure verify proves them with a real sign-in. Either way you install nothing: Get your credentials covers both, and the callback rules that apply to both.
Keep sk_ keys, the OAuth client secret, and every OAuth token server-side. pk_, CONFIGURE_AGENT, and CONFIGURE_OAUTH_CLIENT_ID are the ones the browser gets.
SSO only
Use this when you want "Sign in with Configure" beside your existing providers, and your product keeps working the way it does today.
You do not replace your auth. Configure returns the same shape of identity a Google sign-in returns, so store it where you already store that.
- Put the button on your sign-in page.
redirect-urimust match the registered callback character for character.
html
<script src="https://configure.dev/js/configure.js"></script>
<configure-sso-button
client-id="oc_..."
redirect-uri="http://localhost:3000/auth/configure/callback"
agent-name="Your Agent"
scopes="profile.read profile.search profile.remember profile.commit"
width="100%">
</configure-sso-button>- Generate the callback instead of writing it:
bash
npx configure add callback --framework next--framework takes next, express, or vite. This writes the callback route, the server-side code exchange, and the sign-in button, with the client secret kept on the server. For next the button is a ConfigureSignInButton component that mounts the hosted button. The generated callback exchanges the single-use code once, recovers the PKCE verifier when state is missing, and hands off to the opener in a popup instead of navigating. Those are the four things hand-written callbacks miss: the production checklist covers them.
- Store what comes back in your session, the same way you store a Google sign-in.
That is the whole path. The user now has a Configure identity in your product. Details and the manual version of the exchange: OAuth client reference.
MCP only
Use this when an agent is the product (a texting agent, a chat assistant) and you want the agent to bring users in itself, without adding a sign-in page.
There is no button and no callback. Point your agent at Configure MCP and give it the profile tools:
text
https://mcp.configure.devThe agent starts with no user. When it needs context, it calls configure_connect, which returns a real sign-in link. The agent puts that link in its normal reply, the user taps it and connects, and the following tool calls read the approved profile.
text
User: remember I only fly nonstop
Agent: calls configure_connect, replies with the returned link
User: (taps the link, signs in)
Agent: calls configure_profile_remember, then confirmsTwo rules keep this reliable:
- The agent must include the link
configure_connectreturned, verbatim. Never invent a/connectURL: links are minted per user and a hand-built one cannot work. - Identity comes from the authenticated session, never from arguments. Do not pass
user_id,phone, oragentto a tool.
Unauthenticated agents can list every tool, so a client can see the full surface before anyone connects. Listing is not permission: calls other than configure_connect fail closed until a user has signed in and granted access. Setup and per-client config: Configure MCP.
SDK plus SSO
Use this when you want your own component in your own UI, on your schedule, rather than a login page: a "Connect to Configure" button in a settings panel, an integrations list, or the + menu of a chat.
- Install the SDK and render your own trigger. You control the design; the hosted flow handles sign-in and the permission screens.
bash
npm install configurehtml
<script src="https://configure.dev/js/configure.js"></script>
<div id="configure-entry"></div>
<script>
Configure.personalizationButton({
el: "#configure-entry",
publishableKey: "pk_...",
agent: "your-agent",
agentName: "Your Agent",
variant: "integration",
onEvent(event) {
if (event.type === "configure:linked") {
fetch("/api/configure/session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: event.payload.token }),
});
}
},
});
</script>Store the returned token server-side in your session. It is agent-scoped: keep it out of the model prompt.
After the user is connected, let your agent read through MCP, or read from your backend with the SDK. Both work against the same profile; the choice is who decides when to read.
Component options and placement: Inline UI components.
SSO plus SDK
Use this when Configure is how users sign in, and your backend (not the model) decides when to read the profile.
Do the SSO path. Your session now holds a Configure access token.
Read the profile in your own routes:
ts
import { Configure } from "configure";
const configure = new Configure({
apiKey: process.env.CONFIGURE_API_KEY,
agent: process.env.CONFIGURE_AGENT,
});
app.post("/api/chat", async (req, res) => {
const profile = configure.profile({ token: req.session.configureAccessToken });
const read = await profile.read({ sections: ["identity", "preferences", "summary"] });
const approvedContext = read.profile.format({ guidelines: false });
// Use approvedContext in your prompt, then write back what the turn learned.
const response = await runYourModelLoop({ approvedContext, messages: req.body.messages });
await profile.commit({ messages: req.body.messages, response });
res.json({ text: response.text });
});- When you later want the model itself to decide, hand it the tools instead of the formatted text:
profile.tools()plusprofile.executeTool(), or connect your agent over MCP. Nothing about step 1 or 2 changes.
Full walkthrough: Quick start. Tool dispatch for OpenAI and Anthropic: Handling tool calls.
Going to production
The same three things apply to every path:
- Register your production callback before you deploy. Local setup registers loopback callbacks only. Run
npx configure add origin https://yourapp.com/auth/configure/callback(orconfigure-ai add-origin <url>), confirm it in the browser it opens, then check it withnpx configure verify --offline --redirect-uri https://yourapp.com/auth/configure/callback. Callbacks are additive, so one client covers local and production andCONFIGURE_OAUTH_CLIENT_IDnever changes. Add callback on the dashboard's Sign-in (SSO) page does the same thing without the CLI (Callbacks). - A lost client secret is reissued, not recovered. Secrets are stored hashed, so re-running setup or using New secret on the dashboard's Sign-in (SSO) page issues a new one. Update
CONFIGURE_OAUTH_CLIENT_SECRETeverywhere you deployed it, or sign-in fails withinvalid_client. - Nothing secret reaches the browser.
sk_keys, the OAuth client secret, and access and refresh tokens stay on your server. The browser getspk_and, when your backend chooses to return one, a handoff token for hosted UI.