@withlocus/credits is the server-side SDK for Locus Pro: zero dependencies, built on fetch. It generates idempotency keys and retries with backoff on its own. Use a secret key for management methods and a scoped agent connection credential for agent execution. It should never run in the browser. The current release of @withlocus/credits is 0.5.2, versioned in lockstep with @withlocus/credits-js and @withlocus/credits-react.
This SDK is for enterprise server integrations. Personal accounts connect
agents through MCP OAuth and do not expose tenant secret keys, end-user
tokens, Agent Connection service credentials, or server management APIs.
Constructor
call()
Run a metered API call. slug is "provider/endpoint"; body is the provider’s own request shape.
call() and callRaw() hand you the untouched Response, so you own the body — stream it, or read it once yourself. callJson() and callText() consume it for you and put the result on data.
CallOptions
Returns
CallResult / ParsedCallResult<T>
Idempotency-Key is mandatory on burns and the SDK handles it for you: one
key per call(), reused verbatim across internal retries, so a retry never
double-charges.Agent connections
Create and manage scoped deployment credentials from a secret-key client:mode: "platform" binds the connection to the pooled balance. mode: "end_user" requires externalUserId and binds it to that account. tools.enable contains exact provider/endpoint slugs; omit tools to inherit every tenant-enabled endpoint. Scope is immutable, so create a replacement connection when the account or tools must change.
The 0.5.2 typed helper covers account binding, tools, budgets, and expiry. The
REST create operation and dashboard also support immutable per-connection
pricing overrides for end-user mode; use one of those surfaces when you need
credential-specific markup because this SDK version does not type that field.
Use the returned credential in a separate execution client if your agent calls the REST surface directly:
create() and rotate(). List/get responses include the display prefix, status, expiry, rotation time, revocation time, and lastUsedAt, but never recover the credential.
See Connect an agent for policy and lifecycle details.
Framework MCP presets
Version 0.5.2 converts a newly created or rotated connection into exact MCP configuration shapes without adding runtime dependencies:
Hosted model APIs expect the raw token, while runtime MCP clients expect the complete bearer header. The presets enforce that distinction and reject redacted credentials or invalid URLs. OpenAI presets default approval to
never; pass requireApproval to change it.
See Framework integrations for complete examples and lifecycle guidance.
Also exported
Detailed on other pages rather than here:LocusMcpOAuth and openAiMcpTool for application-owned MCP OAuth; parseMcpToolResult, prepareMcpResultForSynthesis, selectSynthesisAnswer and addCreditAmounts for final-answer synthesis; and the DEFAULT_BASE_URL, HEADERS and PATHS constants if you need the raw HTTP contract the client is built on.
balance()
Read a balance: your wholesale pool, or one end-user’s account.
BalanceResult: { credits: string; usd?: string; raw: unknown }
searchTools()
Find enabled tools from a plain-language capability description. Pass user to apply that end user’s current policy as well as tenant catalog enablement.
query accepts 1–256 characters. limit defaults to 8 and accepts 1–20. Results include the execution slug, tool name, description, category, price or variable-cost marker, request schema, and example arguments.
ledger()
Page through the append-only ledger with cursor pagination and attribution filters.
LedgerParams: { user?, category?, cursor?, limit?, attribution? }
Returns LedgerPage: { entries: unknown[]; nextCursor?: string; raw: unknown }
allocate() / deallocate()
Move credits between your pool and an end-user’s account. The move is atomic and never overdrafts.
topup()
Create a Stripe Checkout session for a top-up. Omit externalUserId to fund your wholesale pool; set it to fund that end-user’s balance instead.
successUrl or cancelUrl is missing or not an absolute HTTP(S) URL, if you pass both or neither of usd/credits, or if the amount isn’t an exact decimal string.
Returns TopupResult: { url, sessionId, externalUserId, quote, bonus?, raw }. The quote may also contain bonus and nextBonusTier; end-user top-ups never earn a volume bonus.
Read the current amount limits and bonus schedule instead of hard-coding them, then poll the session until Stripe’s webhook makes the credits usable:
endUserToken()
Mint a short-lived end-user JWT for the widget or a browser-side MCP connection.
EndUserTokenOptions: expiresIn (seconds, 60–3600, default 3600) and sessionId (16–128 characters) to bind the token to one browser session.
Returns EndUserTokenResult: { token: string; expiresAt: string; expiresIn: number; tokenId: string; externalUserId: string; raw: unknown }
End-user catalog
Fetch every page of the privacy-safe provider catalog visible to one end-user token. The server applies the user’s current provider/endpoint policy and returns only final prices. The helper isfetchCatalog(auth, options), exported by @withlocus/credits-js and @withlocus/credits-react (not by the server SDK):
{ state: 'exact', credits: string, usd: string }; variable and temporarily unavailable entries never fabricate numbers.
Errors
Every non-2xx response throws a typed error you can catch:API reference
The raw HTTP endpoints the SDK wraps.
Quickstart
Set up keys and make your first metered call.